Strange gcc compiler error?

Discussion in 'C++' started by J Cook, May 3, 2011.

  1. J Cook

    J Cook Guest

    Can anyone explain this error? It seems as if the compiler is using
    the name of the first parameter as the temporary object name?

    class Foo
    {
    Foo(int s) {}

    };

    void foo()
    {
    int test = 4;
    Foo(test); // create a temporary. Thinks it is named "test" ??
    }

    int main()
    {
    foo();
    }

    # In function 'void foo()'
    # error: conflicting declaration 'Foo test'
    # 'test' has a previous declaration as 'int test'

    gcc 4.1.2

    Thanks in advance,
    JC
     
    J Cook, May 3, 2011
    #1
    1. Advertising

  2. On 5/3/2011 12:51 PM, J Cook wrote:
    > Can anyone explain this error? It seems as if the compiler is using
    > the name of the first parameter as the temporary object name?
    >
    > class Foo
    > {
    > Foo(int s) {}
    >
    > };
    >
    > void foo()
    > {
    > int test = 4;
    > Foo(test); // create a temporary. Thinks it is named "test" ??
    > }
    >
    > int main()
    > {
    > foo();
    > }
    >
    > # In function 'void foo()'
    > # error: conflicting declaration 'Foo test'
    > # 'test' has a previous declaration as 'int test'
    >
    > gcc 4.1.2


    In order to verify you could use www.comeaucomputing.com/tryitout (they
    compile but don't link), their compiler is very Standard-compliant.

    As to your "error" since 'Foo' is the name of the type, the compiler can
    (and will) interpret

    Foo(test);

    as a declaration of a variable 'test' of type 'Foo', thus trying to
    redeclare 'test' with another type. To avoid that add parentheses

    Foo((test));

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, May 3, 2011
    #2
    1. Advertising

  3. J Cook

    J Cook Guest

    On May 3, 1:01 pm, Victor Bazarov <> wrote:
    > On 5/3/2011 12:51 PM, J Cook wrote:

    \> In order to verify you could usewww.comeaucomputing.com/
    tryitout(they
    > compile but don't link), their compiler is very Standard-compliant.
    >
    > As to your "error" since 'Foo' is the name of the type, the compiler can
    > (and will) interpret
    >
    >      Foo(test);
    >
    > as a declaration of a variable 'test' of type 'Foo', thus trying to
    > redeclare 'test' with another type.  To avoid that add parentheses
    >
    >      Foo((test));


    You are right about the semantic confusion. I had thought of the
    double parenthesis would fix it also, but it does not seem to make any
    difference. I really want to create an unnamed temporary (a common
    task), and can't seem to find a way to hint the parser that this
    should be a Constructor call with one parameter.

    Thanks,
    --JC
     
    J Cook, May 3, 2011
    #3
  4. On 5/3/2011 1:09 PM, Victor Bazarov wrote:
    > On 5/3/2011 1:06 PM, J Cook wrote:
    >> On May 3, 1:01 pm, Victor Bazarov<> wrote:
    >>> On 5/3/2011 12:51 PM, J Cook wrote:

    >> \> In order to verify you could usewww.comeaucomputing.com/
    >> tryitout(they
    >>> compile but don't link), their compiler is very Standard-compliant.
    >>>
    >>> As to your "error" since 'Foo' is the name of the type, the compiler can
    >>> (and will) interpret
    >>>
    >>> Foo(test);
    >>>
    >>> as a declaration of a variable 'test' of type 'Foo', thus trying to
    >>> redeclare 'test' with another type. To avoid that add parentheses
    >>>
    >>> Foo((test));

    >>
    >> You are right about the semantic confusion. I had thought of the
    >> double parenthesis would fix it also, but it does not seem to make any
    >> difference. I really want to create an unnamed temporary (a common
    >> task), and can't seem to find a way to hint the parser that this
    >> should be a Constructor call with one parameter.

    >
    > You can do
    >
    > static_cast<Foo>(test);
    >
    > that should invoke the constructor.


    Or, another way is to cast:

    (Foo)test;

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, May 3, 2011
    #4
  5. J Cook

    Kai-Uwe Bux Guest

    J Cook wrote:

    > Can anyone explain this error? It seems as if the compiler is using
    > the name of the first parameter as the temporary object name?
    >
    > class Foo
    > {
    > Foo(int s) {}
    >
    > };
    >
    > void foo()
    > {
    > int test = 4;
    > Foo(test); // create a temporary. Thinks it is named "test" ??
    > }
    >
    > int main()
    > {
    > foo();
    > }
    >
    > # In function 'void foo()'
    > # error: conflicting declaration 'Foo test'
    > # 'test' has a previous declaration as 'int test'

    [...]

    The compiler treats the marked line not as creating a temporary but as a
    variable declaration of the variable test. At least, that is what the error
    message says.

    What one would expect, is a message: "constructor Foo(int) is private and
    cannot be used in this context.". However, after discarding the private
    constructor, the compiler goes on and tries the default constructor. That's
    why you get a redefinition error message. The compiler does this, because
    clause [8.3/6] says that one way of reading

    Foo(test);

    is:

    Foo test;


    Best,

    Kai-Uwe Bux
     
    Kai-Uwe Bux, May 3, 2011
    #5
  6. J Cook

    Öö Tiib Guest

    On May 3, 8:10 pm, Victor Bazarov <> wrote:
    > On 5/3/2011 1:09 PM, Victor Bazarov wrote:
    >
    >
    >
    >
    >
    > > On 5/3/2011 1:06 PM, J Cook wrote:
    > >> On May 3, 1:01 pm, Victor Bazarov<> wrote:
    > >>> On 5/3/2011 12:51 PM, J Cook wrote:
    > >> \> In order to verify you could usewww.comeaucomputing.com/
    > >> tryitout(they
    > >>> compile but don't link), their compiler is very Standard-compliant.

    >
    > >>> As to your "error" since 'Foo' is the name of the type, the compiler can
    > >>> (and will) interpret

    >
    > >>> Foo(test);

    >
    > >>> as a declaration of a variable 'test' of type 'Foo', thus trying to
    > >>> redeclare 'test' with another type. To avoid that add parentheses

    >
    > >>> Foo((test));

    >
    > >> You are right about the semantic confusion. I had thought of the
    > >> double parenthesis would fix it also, but it does not seem to make any
    > >> difference. I really want to create an unnamed temporary (a common
    > >> task), and can't seem to find a way to hint the parser that this
    > >> should be a Constructor call with one parameter.

    >
    > > You can do

    >
    > > static_cast<Foo>(test);

    >
    > > that should invoke the constructor.

    >
    > Or, another way is to cast:
    >
    >      (Foo)test;


    Still does not work since Foo constructor is private in example code.
    If it is made public and explicit (that it usually should be with just
    one parameter) then such monster works:

    (void)Foo(test);
     
    Öö Tiib, May 3, 2011
    #6
  7. J Cook

    James Kanze Guest

    On May 3, 6:36 pm, Öö Tiib <> wrote:
    > On May 3, 8:10 pm, Victor Bazarov <> wrote:
    >
    >
    >
    > > On 5/3/2011 1:09 PM, Victor Bazarov wrote:

    >
    > > > On 5/3/2011 1:06 PM, J Cook wrote:
    > > >> On May 3, 1:01 pm, Victor Bazarov<> wrote:
    > > >>> On 5/3/2011 12:51 PM, J Cook wrote:
    > > >> \> In order to verify you could usewww.comeaucomputing.com/
    > > >> tryitout(they
    > > >>> compile but don't link), their compiler is very Standard-compliant.

    >
    > > >>> As to your "error" since 'Foo' is the name of the type, the compiler can
    > > >>> (and will) interpret

    >
    > > >>> Foo(test);

    >
    > > >>> as a declaration of a variable 'test' of type 'Foo', thus trying to
    > > >>> redeclare 'test' with another type. To avoid that add parentheses

    >
    > > >>> Foo((test));

    >
    > > >> You are right about the semantic confusion. I had thought of the
    > > >> double parenthesis would fix it also, but it does not seem to make any
    > > >> difference. I really want to create an unnamed temporary (a common
    > > >> task), and can't seem to find a way to hint the parser that this
    > > >> should be a Constructor call with one parameter.

    >
    > > > You can do

    >
    > > > static_cast<Foo>(test);

    >
    > > > that should invoke the constructor.

    >
    > > Or, another way is to cast:

    >
    > > (Foo)test;

    >
    > Still does not work since Foo constructor is private in example code.
    > If it is made public and explicit (that it usually should be with just
    > one parameter) then such monster works:
    >
    > (void)Foo(test);


    Or simply putting the entire expression in parentheses:

    (Foo( test ));

    (But it sure looks funny:).)

    --
    James Kanze
     
    James Kanze, May 3, 2011
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Yan
    Replies:
    0
    Views:
    1,154
  2. Ram
    Replies:
    0
    Views:
    2,878
  3. Gernot Frisch

    gcc strange error

    Gernot Frisch, Aug 6, 2004, in forum: C++
    Replies:
    2
    Views:
    419
    John Harrison
    Aug 6, 2004
  4. grundmann
    Replies:
    8
    Views:
    354
    grundmann
    Sep 24, 2005
  5. Tsb

    GCC compiler error

    Tsb, Oct 12, 2007, in forum: C Programming
    Replies:
    46
    Views:
    1,412
    Spoon
    Oct 22, 2007
Loading...

Share This Page