jj@idris.id.dk (Jesper Joergensen [ris]) (01/20/90)
THIS BUG IS A SERIOUS ONE, since the compiler fails to emit an error message
for an invalid statement, BUT NO CODE IS GENERATED for the statement.
It is connected to the good old const problem, towards which the compiler's
attitude has changed a lot across the latest releases. Some other error
messages are still missing, which I will try and summarize in this postng as
well.
I am using: g++ 1.36.3 (just installed it)
based on: gcc 1.36 (can't get my hands on 1.36.92 anywhere)
under: Ultrix V2.2-1 Worksystem V1.1 System #2
on a: DEC VAXstation 2000
Much of the errors missing were present in 1.36.3-, while some of them have
never been. I am very confused, since nothing has changed in the language since
1.36.3-. I AM VERY CONFUSED and humbly asks for an explanation, PLEASE respond.
The below program contains a series of errors, which does not cause any
messages from the compiler. All these errors are marked with an // ERROR: ...
comment. Some of the methods have sideeffects to show there invocations.
****** SAMPLE PROGRAM START ******
extern "C" int printf(const char* ...) ;
class Test {
const char *name ;
int member ;
public:
Test(const char* name1, int member1) { name = name1 ; member = member1 ; }
Test(const Test &x) { member = x.member ; }
/* This method is non-const, but it returns a const result */
const Test &operator=(const Test &r) {
member = - r.member ; // NOTE: side effect
return *this ;
}
/* This method is const and it returns a pointer to a const result */
const Test *operator&() const { // NOTE: side effect of operator =
*this = *this ; // ERROR: non-const method called within const method
return this ;
}
/* This friend modifies the non-const reference argument */
friend void change_sign(Test &x) {
x.member = - x.member ;
}
/* This friend prints the name and contents of the class object */
friend void print(const Test &x) {
printf("%s.member = %d\n", x.name, x.member) ;
}
} ;
int main(int argc, const char *argv[]) {
const Test C("C",1) ;
Test V("V",2) ;
&V ; // should change sign of V.member
print(C) ; print(V) ;
C = V ; // ERROR: non-const method applied to const object
print(C) ; print(V) ;
(V = C) = V ; // ERROR: non-const method applied to const object
// (result of (V = C) is reference to const)
print(C) ; print(V) ;
change_sign(V = C) ; // ERROR: passing non-const reference from const object
// (result of (V = C) is reference to const)
print(C) ; print(V) ;
*(&V) = C ; // ERROR: non-const method applied to const object
// (the result of &V is a pointer to const)
print(C) ; print(V) ;
return 0 ;
}
******* SAMPLE PROGRAM END *******
NON of the above errors were detected by the compiler and some of the erroneuos
statements doesn't have effect when executed. Below is the output from the
program.
****** PROGRAM OUTPUT START ******
C.member = 1
V.member = 2 /* 1/ no effect of &V (should change sign) */
C.member = 1 /* 2/ C = V had no effect */
V.member = 2
C.member = 1 /* 3/ (V = C) = V changed sign of C twice in V */
V.member = 1 /* hence it corresponds to V = C ; V = V ; */
C.member = 1
V.member = 1 /* 4/ change_sign changed sign of the result in V */
C.member = 1
V.member = 1 /* 5/ no effect of *(&V) = C (should be negated C.member) */
******* PROGRAM OUTPUT END *******
1/ the & operator calls the = operator on *this, so the sign should be changed
implicitly on the argument to &. This does not happen, since = is not
invoked at all (it IS an illegal invocation, but no error shows up).
2/ the assignment C = V had no effect on C, since = is not invoked (it IS an
illegal invocation, but still no error shows up).
3/ shows the expected result since the result of = is a reference to the left
hand operand, but it should still be illegal to invoke a non-const method
on a const function result.
4/ shows the expected result since the result of = is a reference to the left
hand operand, but is should still be illegal to pass the const reference
result as a non-const reference parameter.
5/ the = operator was not invoked, since that would have stored the negative
value of C.member in V.member. It is also an illegal invocation of the
non-const method = on the const object *(&V), but still no error message
shows up.
Can you explain this to me ?????
Thanks in advanve
Jesper Jorgensen jj@idris.id.dk
Research associate
Department of Computer Science
Technical University of Denmark
DK-2800 Lyngby
DENMARK