Hello,

I'd like to point your attention to a weird linker error I see on my system
on gcc version 4.3.3, 4.4.1 and 4.4.2.
I could not find anything related to this in bugzilla using the keyword
typedef.
Here are three files I use to produce the error:

/*
 * bug.cpp
 *
 *  Created on: 07.11.2009
 *      Author: Wolf Lammen
 */

#include "A.h"

int main()
{
        A::B().foo();
        return 0;
}

===========================================================================
/*
 * A.h
 *
 *  Created on: 07.11.2009
 *      Author: Wolf Lammen
 */

/*
 * this compiles and links fine, if I
 * a) inline foo i.e use "void foo(){}" and remove foo() from A.cpp
 * b) avoid the keyword typedef and use "struct B { void foo(); };" instead
 */

struct A {
        typedef struct {
                void foo();
        } B;
};

===========================================================================
/*
 * A.cpp
 *
 *  Created on: 07.11.2009
 *      Author: Wolf Lammen
 */

#include "A.h"

void A::B::foo() {}

===========================================================================

Here's the output I get with g++, latest version
(similar for 4.3.3 or 4.4.1)

w...@kubuntu-910:~/bug$ ../bin/gcc-4.4.2/bin/g++ --version
Copyright (C) 2009 Free Software Foundation, Inc.
Dies ist freie Software; die Kopierbedingungen stehen in den Quellen. Es
gibt KEINE Garantie; auch nicht für MARKTGÄNGIGKEIT oder FÜR SPEZIELLE ZWECKE.

w...@kubuntu-910:~/bug$ cat A.h
/*
 * A.h
 *
 *  Created on: 07.11.2009
 *      Author: Wolf Lammen
 */

/*
 * this compiles fine, if I
 * a) inline foo i.e use void foo(){} and remove foo() from A.cpp
 * b) avoid the keyword typedef and use struct B { void foo(); }; instead
 */

struct A {
        typedef struct {
                void foo();
        } B;
};
w...@kubuntu-910:~/bug$ ~/bin/gcc-4.4.2/bin/g++ -O0 -g3 -Wall -c
-fmessage-length=0 -MMD -MP -MF"A.d" -MT"A.d" -o"A.o" "A.cpp"
w...@kubuntu-910:~/bug$ ../bin/gcc-4.4.2/bin/g++ -O0 -g3 -Wall -c
-fmessage-length=0 -MMD -MP -MF"bug.d" -MT"bug.d" -o"bug.o" "bug.cpp"
w...@kubuntu-910:~/bug$ ../bin/gcc-4.4.2/bin/g++  -o"test"  ./A.o ./bug.o
./bug.o: In function `main':
/home/wolf/bug/bug.cpp:12: undefined reference to `A::B::foo()'
collect2: ld gab 1 als Ende-Status zurück

There is a simple work-around:
use
        struct B{
                void foo();
        };
instead of the typedef struct {...} in file A.h, and everything compiles
and links fine (see below):

w...@kubuntu-910:~/bug$ ../bin/gcc-4.4.2/bin/g++ --version
g++ (GCC) 4.4.2
Copyright (C) 2009 Free Software Foundation, Inc.
Dies ist freie Software; die Kopierbedingungen stehen in den Quellen. Es
gibt KEINE Garantie; auch nicht für MARKTGÄNGIGKEIT oder FÜR SPEZIELLE ZWECKE.

w...@kubuntu-910:~/bug$ ~/bin/gcc-4.4.2/bin/g++ -O0 -g3 -Wall -c
-fmessage-length=0 -MMD -MP -MF"A.d" -MT"A.d" -o"A.o" "A.cpp"
w...@kubuntu-910:~/bug$ ../bin/gcc-4.4.2/bin/g++ -O0 -g3 -Wall -c
-fmessage-length=0 -MMD -MP -MF"bug.d" -MT"bug.d" -o"bug.o" "bug.cpp"
w...@kubuntu-910:~/bug$ ../bin/gcc-4.4.2/bin/g++  -o"test"  ./A.o ./bug.o
w...@kubuntu-910:~/bug$ cat A.h
/*
 * A.h
 *
 *  Created on: 07.11.2009
 *      Author: Wolf Lammen
 */

/*
 * this compiles fine, if I
 * a) inline foo i.e use void foo(){} and remove foo() from A.cpp
 * b) avoid the keyword typedef and use struct B { void foo(); }; instead
 */

struct A {
        struct B{
                void foo();
        };
};

Although there is a simple work-around (with slightly different semantics), the
example is AFAIK correct C++ code, that shouldn't rise any problems.

cheers

Wolf Lammen


-- 
           Summary: linker error with typedef struct
           Product: gcc
           Version: 4.4.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: ookami1 at gmx dot de
 GCC build triplet: x86_64-unknown-linux-gnu
  GCC host triplet: x86_64-unknown-linux-gnu
GCC target triplet: x86_64-unknown-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42011

Reply via email to