Linker problem that depends on *.h include order 
Author Message
 Linker problem that depends on *.h include order

Hello,

I found a very strange behaviour in Microsoft's VC6.0 cl
code generation for forward declared classes.

I have a class Foo that has a forward declaration of class Bar in its header
and I have a main in FooBar.cpp that includes Foo.h and Bar.h
If I compile FooBar.cpp and include first Bar.h and then Foo.h in it
I get an linker error :

FooBar.obj : error LNK2001: unresolved external symbol
"public: void __thiscall Test::Foo::f(struct Test::Bar &)"

fb.exe : fatal error LNK1120: 1 unresolved externals

In FooBar.obj I find the symbol

but in Foo.obj it is named

(...UBar... vs ...VBar...)

If you change the order in which FooBar.cpp includes Foo.h and Bar.h everything
is OK.  See the code at the end of this mail.

In the example problem vanishes if I drop the namespaces. However,in larger
projects
I had the same trouble even after dropping all namespaces (except std) from
my code.

What I need is a workaround, e.g. a way to convince the MS-linker that
..UBar.. and ...VBar.. are the same symbols (changing the code generating
part of cl is no viable option I guess :-)

Best regards

Burkhard Neppert
b _dot_ neppert _at_ dr-staedtler _dot_ de

// Foo.h
// ==================================================
namespace Test {
class Bar;
struct Foo {
void f(Bar & b);

Quote:
};
}

// Foo.cpp
// ==================================================
#ifndef FOO_H
#define FOO_H
#include "Foo.h"
#include "Bar.h"
namespace Test {
void Foo::f(Bar & b) { }
Quote:
}

#endif

// Bar.h
// ==================================================
#ifndef BAR_H
#define BAR_H
namespace Test {
struct Bar {
public:
virtual void nop();

Quote:
};
}

#endif

// Bar.cpp
// ==================================================

#include "Bar.h"

namespace Test {
void Bar::nop() {
int i=0;

Quote:
}
}

// FooBar.cpp
// ==================================================

/** This include order gives an unresolved
external symbol when linking.
Just swap the lines and linking works !
*/
#include "Bar.h"
#include "Foo.h"

using namespace Test;
int main(int, char**) {
Foo f;
Bar b;
f.f(b);

Quote:
}

// nmake - makefile
//==================================================

all: bug

bug: Foo.obj Bar.obj FooBar.obj
link /MAP FooBar.obj -nologo Foo.obj Bar.obj -out:will_not_link.exe

Foo.obj:
cl -c Foo.cpp

Bar.obj:
cl -c Bar.cpp

FooBar.obj:
cl -c FooBar.cpp

Burkhard Neppert
b _dot_ neppert _at_ dr-staedtler _dot_ de



Sun, 15 Feb 2004 23:25:32 GMT  
 Linker problem that depends on *.h include order

Quote:
> I found a very strange behaviour in Microsoft's VC6.0 cl
> code generation for forward declared classes.

> I have a class Foo that has a forward declaration of class Bar in its
header
> and I have a main in FooBar.cpp that includes Foo.h and Bar.h
> If I compile FooBar.cpp and include first Bar.h and then Foo.h in it
> I get an linker error :

> FooBar.obj : error LNK2001: unresolved external symbol
> "public: void __thiscall Test::Foo::f(struct Test::Bar &)"

> fb.exe : fatal error LNK1120: 1 unresolved externals

If you'd use a higher warning level (level 3, for instance) and/or read the
warnings the compiler issues, it would have been easy to solve the problem.
Here is what /W3 says:

foo.h(4) : warning C4099: 'Bar' : type name first seen using 'struct' now
seen using 'class'
        bar.h(6) : see declaration of 'Bar'

Quote:

> In FooBar.obj I find the symbol

> but in Foo.obj it is named

> (...UBar... vs ...VBar...)

UBar vs. VBar probably means class vs. struct.

Quote:
> What I need is a workaround, e.g. a way to convince the MS-linker that
> ..UBar.. and ...VBar.. are the same symbols (changing the code generating
> part of cl is no viable option I guess :-)

What about changing 'class Bar' to 'struct Bar' in foo.h? ;-)

Quote:
> // Foo.cpp
> // ==================================================
> #ifndef FOO_H
> #define FOO_H
> #include "Foo.h"
> #include "Bar.h"
> namespace Test {
> void Foo::f(Bar & b) { }
> }
> #endif

BTW: Why do you write guards into a .CPP file? Usually I put them into .H
file. At least I would call them like FOO_CPP in a .CPP file.

Regrads
    Heinz



Mon, 16 Feb 2004 00:20:27 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. linker error depending on what way of using MFC is chosen

2. linker error depending on way to use MFC

3. Linker problem - undefined reference after including math lib

4. Linker Problem can any one tell me what library to include

5. linker problem can any one tell me what lib to include

6. linker Problem Can any one tell me what lib to include

7. linker problem can any one tell me what lib to include

8. Compiler gen'd depends (was: nested includes)

9. Changing Order Of Linker Arguments (OBJ-Files) from IDE

10. Newbie: Linker's Link order

11. High order/low order problem

12. Controlling the linker and function ordering

 

 
Powered by phpBB® Forum Software