I have a header file with something like the following inline function foo(), that uses a local class:
inline void foo() {
struct Local {
static inline int bar() {
return 0;
}
};
Local::bar();
}
If I include this heade in two compilation units, I get a linker duplicate symbol for Local::bar():
Linking...
ProblemTest.obj : error LNK2005: "public: static int __cdecl `void __cdecl foo(void)'::`2'::Local::bar(void)" (?bar@Local@?1??foo@@YAXXZ@SAHXZ) already defined in Test.obj
Release/ProblemTest.exe : fatal error LNK1169: one or more multiply defined symbols found
Is this a compiler/linker bug?
Is there any workaround? (In the real-world example foo() is also a member function and the code of Local is generated. It has to be a local class, because it needs to have private access to foo's class.)
Daniel
#ifndef _YOUR_HEADER_FILE_NAME_H_
#define _YOUR_HEADER_FILE_NAME_H_
inline void foo()
{
}
#endif // _YOUR_HEADER_FILE_NAME_H_
Also take a look at #pragma once
--
Cheers
Check Abdoul [VC++ MVP]
-----------------------------------
"Daniel Lohmann" <dan...@uni-koblenz.de> wrote in message
news:947FE98C-A737-4B82...@microsoft.com...
However, it has nothing to do with my question :-(
As I told the problem is that the *linker* is asserting a duplicate
symbol for an identifier that is a member of a function-local class
and therefore should have no linkage at all.
Daniel
I should have mentioned that I am using VC.NET 2003.
To me this definitly looks like a compiler/linker bug. The linker is
asserting a duplicate symbol for an entity (foo__Local::bar) that,
- is defined inline
- has, because it is a member of a function-local class, no linkage at
all - regardless of beeing defined inline or not! (According to the
standard) .
I would appreciate if somebody from MS could confirm that.
Regards
Daniel
>Hi,
>
>I have a header file with something like the following inline function foo(), that uses a local class:
>
>inline void foo() {
> struct Local {
> static inline int bar() {
> return 0;
> }
> };
> Local::bar();
>}
>
>
>If I include this heade in two compilation units, I get a linker duplicate symbol for Local::bar():
>
>Linking...
>ProblemTest.obj : error LNK2005: "public: static int __cdecl `void __cdecl foo(void)'::`2'::Local::bar(void)" (?bar@Local@?1??foo@@YAXXZ@SAHXZ) already defined in Test.obj
>Release/ProblemTest.exe : fatal error LNK1169: one or more multiply defined symbols found
>
>
>Is this a compiler/linker bug?
FWIW, in the few minutes I spent researching this, I couldn't find anything
in the standard to make me think that it is not a bug. (I looked at sections
7.1.2 and 3.5.)
>Is there any workaround? (In the real-world example foo() is also a member function and the code of Local is generated. It has to be a local class, because it needs to have private access to foo's class.)
I can think of two workarounds, modulo what you mean by "code of Local is
generated":
1. Make foo() non-inline and define it in one and only one place.
2. Make Local a nested class of the real foo's class. As Local needs access
to foo's class, this will probably only work in VC.NET, which tracks the
defect report which grants nested classes access to their enclosing classes'
members.
--
Doug Harrison
Microsoft MVP - Visual C++
Thanks for posting in the community.
First I would like to confirm my understanding of your issue.
From your description, I understand that you get a linker duplicate symbol
for Local::bar() when including that header(Local::bar() definition) in two
compilation units.
Have I understood you right? If anything misunderstood, please feel free to
let me know.
After review this thread, I see the problem still persists, would you
please upload a self-contained sample project to help us isolate your
problem for further troubleshooting.
Thanks!
Best regards,
Gary Chang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
--------------------
>>Is this a compiler/linker bug?
>
>FWIW, in the few minutes I spent researching this, I couldn't find anything
>in the standard to make me think that it is not a bug. (I looked at sections
>7.1.2 and 3.5.)
Yes, seems to be a bug. I do really wonder, because I can't believe
that nobody else comes to the idea to use a local class in an inline
function. Seems to be pretty basic stuff to me...
>>Is there any workaround? (In the real-world example foo() is also a member function and the code of Local is generated. It has to be a local class, because it needs to have private access to foo's class.)
>
>I can think of two workarounds, modulo what you mean by "code of Local is
>generated":
>
>1. Make foo() non-inline and define it in one and only one place.
>
>2. Make Local a nested class of the real foo's class. As Local needs access
>to foo's class, this will probably only work in VC.NET, which tracks the
>defect report which grants nested classes access to their enclosing classes'
>members.
Thanks a lot, but both do not work. I see that it is time to pass some
more information why I am using this:
The code is genereated by an C++ aspect weaver (AspectC++
http://www.aspectc.org), which is an Source-To-Source transformation
tool for aspect-oriented programming (http://www.aosd.net) in C++.
It uses g++ or VisualC++ as backend compiler. The mentioned code works
fine with g++, but not with VC. I don't want to go in too much details
here, however, the transformation model needs to place additional
functions somewhere, that have exactly the same access privileges as a
specific member function. Think of foo() beeing a class member
function in the sample code, I need to insert additional functions
that have the same access privileges than foo().
1) The generated code is woven into user-defined code, so your option
1 is not suitable. If the user-defined code uses an inline
implementation we can't change that.
2) bar() needs to be inside a local class of foo(), because only in
this case it has excactly the same access privileges. The important
difference from a simple local class is the handling related to
friends:
class A {
static int i;
friend B::foo();
};
class B {
public:
void foo() {
A::i = 4711; // legal, because foo is friend
struct Local {
void bar() {
A::i = 4711; // legal, because members of local
//classes
// have the same access than the
// enclosing function
}
};
Local::bar();
}
};
The code of bar() in the above sample would not compile, if Local is a
local class of B.
Regards
Daniel
>Hi Daniel,
>
>Thanks for posting in the community.
>
>First I would like to confirm my understanding of your issue.
>From your description, I understand that you get a linker duplicate symbol
>for Local::bar() when including that header(Local::bar() definition) in two
>compilation units.
>
>Have I understood you right? If anything misunderstood, please feel free to
>let me know.
Hi Gary,
Thanks a lot for your assistance!
At first I should mention that I now have also opend an official
incident at MS under the code SRQ040130600621. However, I believe that
the topic might be of interest for the community, too.
>After review this thread, I see the problem still persists, would you
>please upload a self-contained sample project to help us isolate your
>problem for further troubleshooting.
Attached is a simple example project.
Regards
Daniel Lohmann
>Hi Daniel,
>
>Thanks for posting in the community.
>
>First I would like to confirm my understanding of your issue.
>From your description, I understand that you get a linker duplicate symbol
>for Local::bar() when including that header(Local::bar() definition) in two
>compilation units.
>
>Have I understood you right? If anything misunderstood, please feel free to
>let me know.
Hi Gary,
Thanks a lot for your assistance!
At first I should mention that I now have also opend an official
incident at MS under the code SRQ040130600621. However, I believe that
the topic might be of interest for the community, too.
>After review this thread, I see the problem still persists, would you
>please upload a self-contained sample project to help us isolate your
>problem for further troubleshooting.
A simple example project (VC6 and VC7.1, 3,5kb ) that demonstrates the
error is available at
http://www4.informatik.uni-erlangen.de/~lohmann/ProblemTest.zip
Regards
Daniel Lohmann
>Hi Daniel,
>
>Thanks for posting in the community.
>
>First I would like to confirm my understanding of your issue.
>From your description, I understand that you get a linker duplicate symbol
>for Local::bar() when including that header(Local::bar() definition) in two
>compilation units.
>
>Have I understood you right? If anything misunderstood, please feel free to
>let me know.
Hi Gary,
Thanks a lot for your assistance!
At first I should mention that I now have also opend an official
incident at MS under the code SRQ040130600621. However, I believe that
the topic might be of interest for the community, too.
>After review this thread, I see the problem still persists, would you
>please upload a self-contained sample project to help us isolate your
>problem for further troubleshooting.
A simple example project (VC6 and VC7.1, 3,5kb ) that demonstrates the
Thanks for your reply!
I consult your problem to the US-VC++ team, they confirmed that it is a
known issue to the latest VC++ compiler, and it had already been logged
into the internal database.
Thanks for your valuable feedback and concerns to the VC++ product!