f



Cant define global instance with no arguments

Hello

I try to define a global instance:

//--- example 1----
struct A
{ A()    {};
  void foo() {};
};
extern A a1;
A a1();
int main( )
{ a1.foo();
}
//----------------

GCC 3.2.2 comes up with the error message
" `A a1()' redeclared as different kind of symbol"
If I change the line "A a1();" to "A a1;" then it works. 

 
Also the following example works fine.

//--- example 2 ----
struct A
{ A(int) {};
  void foo() {};
};
extern A a2;
A a2(3);
int main( )
{ a2.foo();
}
//----------------


The reason why the I dont leave the parathesis away is, the
constructor arguments are defined by a macro. Thus, at the line where
a is defined, it is not known wheter there are no arguments or any
number of arguments.

//--- example 3 ----
#define ARGUMENTS
// somewhere else:
A a( ARGUMENTS );
//----------------

OK, I could include the parentesis within the macro, like "#define
ARGUMENTS (1)" for any number of arguments and "#define ARGUMENTS" for
no arguments. But I neverthelless like to know what is wrong with
example 1.

Thank you & Greeetings

Flo

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
spamadress
6/28/2003 11:13:22 PM
comp.lang.c++.moderated 10738 articles. 1 followers. allnor (8509) is leader. Post Follow

2 Replies
623 Views

Similar Articles

[PageSpeed] 37

spamadress@bigfoot.com (Sensorflo) writes:

> Hello
>
> I try to define a global instance:
>
> //--- example 1----
> struct A
> { A()    {};
>   void foo() {};
> };
> extern A a1;

> A a1();

This has the same syntax as:

  int foo();

So it is a function declaration. Search groups.google.com for 'Most
    vexing parse' and you should find some threads about it. If you
    have Scott Meyer's _Effective STL_ it is Item 6.


> int main( )
> { a1.foo();
> }
> //----------------
>
> GCC 3.2.2 comes up with the error message
> " `A a1()' redeclared as different kind of symbol"
> If I change the line "A a1();" to "A a1;" then it works. 
>
>  
> Also the following example works fine.
>
> //--- example 2 ----
> struct A
> { A(int) {};
>   void foo() {};
> };
> extern A a2;
> A a2(3);

3 is not a type. To escape from the aforementioned most vexing parse,
    you must have a parameter that is not a type and also not a
    constructor call. So 3 works.

> int main( )
> { a2.foo();
> }
> //----------------
>
>
> The reason why the I dont leave the parathesis away is, the
> constructor arguments are defined by a macro. Thus, at the line where
> a is defined, it is not known wheter there are no arguments or any
> number of arguments.
>
> //--- example 3 ----
> #define ARGUMENTS
> // somewhere else:
> A a( ARGUMENTS );
> //----------------
[snip]

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
llewelly
6/29/2003 10:12:24 PM
On 28 Jun 2003 19:13:22 -0400, spamadress@bigfoot.com (Sensorflo)
wrote in comp.lang.c++.moderated:

> Hello
> 
> I try to define a global instance:
> 
> //--- example 1----
> struct A
> { A()    {};
>   void foo() {};
> };
> extern A a1;
> A a1();

The line above does not define an object of type A named a1.  It
prototypes a function named a1 that accepts no arguments and returns
an object of type A.

> int main( )
> { a1.foo();
> }
> //----------------
> 
> GCC 3.2.2 comes up with the error message
> " `A a1()' redeclared as different kind of symbol"

See above as to why.  You defined a1 as file scope to be a function,
now you are trying to use it as an object.

> If I change the line "A a1();" to "A a1;" then it works. 

This is the proper way to define an object.

> Also the following example works fine.
> 
> //--- example 2 ----
> struct A
> { A(int) {};
>   void foo() {};
> };
> extern A a2;
> A a2(3);
> int main( )
> { a2.foo();
> }
> //----------------
> 
> 
> The reason why the I dont leave the parathesis away is, the
> constructor arguments are defined by a macro. Thus, at the line where
> a is defined, it is not known wheter there are no arguments or any
> number of arguments.
> 
> //--- example 3 ----
> #define ARGUMENTS
> // somewhere else:
> A a( ARGUMENTS );
> //----------------
> 
> OK, I could include the parentesis within the macro, like "#define
> ARGUMENTS (1)" for any number of arguments and "#define ARGUMENTS" for
> no arguments. But I neverthelless like to know what is wrong with
> example 1.
> 
> Thank you & Greeetings
> 
> Flo

You need to note the difference between:

    A ai(void);		// #1

.....and:

    A ai(3);		// #2

.....and:

    A ai();			// #3

There is absolutely no question that #1 is a function prototype.
There is absolutely no question that #2 is a definition of an object,
assuming there is an appropriate constructor that accepts a single
parameter of type int, or some type that an int can be converted to.

#3 is ambiguous.  Is it defining an object and invoking its default
constructor, or is it prototyping a function accepting no arguments?
There was a conscious decision in the C++ language to make () in
function prototypes exactly equivalent to (void).

IIRC Bjarne Stroustrup himself made that decision quite early on, as
he mentions in one of his books that he found the "(void)" notation
ugly.  But I may be misremembering that.

In any case, the language standard is quite clear in how the ambiguity
is resolved.  It specifically requires that anything that can be a
function prototype is a function prototype.

-- 
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Jack
6/29/2003 10:22:36 PM
Reply: