“Wojtek Lerch” <wojtek_l@yahoo.ca> wrote in message
news:boe1qp$81j$1@inn.qnx.com…
Bill Caroselli <> qtps@earthlink.net> > wrote:
I found out further that with the single constructor:
LGadmin ( int x = 0 );
I can instanciate it with:
LGadmin log;
But not with:
LGadmin log();
Of course not – the above is a function declaration, equivalent to
LGadmin log( void );
In other words, what you are running into is a result of the tension between
retention of backwards compatibility with C, and the formal semantics of
C++.
The application doesn’t conform to the specifications, and the version of
Watcom –
is it 10.6? – fails to catch the error.
Specifically, C compatibility in C++ from its non-standard origins, through
the
ARM/ANSI base document and eventually to ISO C++, specifies that a
declaration of the form:
();
is equivalent to the following declaration:
(void);
Note: it specifically disallows “()” as meaning an uncertain argument list,
but retains
it as a no-argument list.
However, the ambiguity resolution rules state that any statement that may be
interpreted
as either a declaration or an expression, shall be considered to be a
declaration (ARM
section 6.8, ISO C++ section 8.2).
This means that, while what you expect is an initializer, and therefore an
expression, it is
interpreting as a declaration of a function, so the log.Put is not
syntactically correct, since
the “.” member accessor is only valid for an aggregate type, but the type of
log is a function
declaration, so the resulting expression may only be a function reference.
Note that even if it interpreted:
LGAdmin log();
as an initializer, you’d still be in trouble, because the
LGAdmin::LGAdmin(int x = 0)
and LGAdmin::LGAdmin(void) could not be disambiguated. Although, you may
not believe there is an LGAdmin::LGAdmin(void), don’t forget that the
compiler
will always generate one if it doesn’t exist as with copy constructors, to
provide
proper initializer behavior.
So, while you view:
LGAdmin::LGAdmin(void) : LGAdmin(0) { }
…
LGAdmin log;
as ugly, it is correct from two perspectives: avoiding ambiguity, as well as
avoiding implicit dependencies on compiler-generated constructors.
Watcom/QNX4 accepted both.
Not the version I have here:
$ cc foo.cc || cat foo.cc
/usr/watcom/10.7/bin/wpp386 -zq -ms -3r -i=/usr/include -i=/usr/watcom/10.7/
usr/include foo.cc
foo.cc(13): Error! E040: (col 10) expression for ‘.’ must be a class,
struct or union
cc: /usr/watcom/10.7/bin/wpp386 exited 2
#include <stdio.h
class X {
int val;
public:
X( int v = 0 ) : val(v) {}
foo( void ) { printf( “%d\n”, val ); }
};
X x();
int main( void ) {
x.foo();
return 0;
}