|
-
April 16th, 2008, 04:52 PM
#1
Question about internal linkage
Hi guys,
I have an interesting scenario I've tested that really doesn't make any sense to me. First note that I'm using the Visual Studio 2008 compiler.
I have 3 files:
Foo.h
A.cpp
B.cpp
In Foo.h, I have the following:
Code:
class foo
{
static int s_member;
};
int foo::s_member = 14;
In A.cpp and in B.cpp, I do the following (code is identical in both):
Code:
static int maintest()
{
foo<0> myfoo;
}
When I compile and link this code, the linker fails saying that two definitions of s_member has been found. This is what I expected. Now let's change the implementations a bit:
Foo.h is now this:
Code:
template< unsigned int t_val >
class foo
{
static int s_member;
};
template< unsigned int t_val >
int foo<t_val>::s_member = 14;
Both A.cpp and B.cpp have been changed to this:
Code:
static int maintest()
{
foo<0> myfoo;
}
In the second scenario, the linker does not fail. I would expect it to fail. Since we're instantiating the class with the same template arguments, both files should be referencing the same static member, and thus the same static member should be getting duplicated between translation units *just* like the former scenario. What is happening here? Where is the static *actually* stored?
::EDIT::
Note that A.cpp and B.cpp both include "foo.h", this should have been obvious but I just wanted to mention it.
--MrDoomMaster
--C++ Game Programmer
Don't forget to rate me if I was helpful!
-
April 16th, 2008, 07:11 PM
#2
Re: Question about internal linkage
 Originally Posted by MrDoomMaster
In the second scenario, the linker does not fail. I would expect it to fail. Since we're instantiating the class with the same template arguments, both files should be referencing the same static member, and thus the same static member should be getting duplicated between translation units *just* like the former scenario. What is happening here?
It seems that VC++ initializes the templates static field only if necessary (in compliance with the standard), and only once.
But, it also seems that if you put different definitions of the static in different translation units, then VC++ will simply use the 'first found'. AFAIK that violates the 'one definition rule'.
- petter
-
April 16th, 2008, 07:34 PM
#3
Re: Question about internal linkage
 Originally Posted by wildfrog
It seems that VC++ initializes the templates static field only if necessary (in compliance with the standard), and only once.
But, it also seems that if you put different definitions of the static in different translation units, then VC++ will simply use the 'first found'. AFAIK that violates the 'one definition rule'.
- petter
Thanks for your response to my inquiry. Could you explain what you mean by "first found"? How does this violate ODR (Note that I already am a little bit fuzzy on the definition of ODR)?
--MrDoomMaster
--C++ Game Programmer
Don't forget to rate me if I was helpful!
-
April 16th, 2008, 08:10 PM
#4
Re: Question about internal linkage
Actually "first found" is just my assumtion, but you'll probably have to ask the folks as Microsoft on how it actually works.
Try adding some code to your second sample, intialize s_member in both you code files:
Code:
//a.cpp
int initA() { return 5; }
int foo<0>::s_member = initA();
static int maintest()
{
foo<0> myfoo;
}
Code:
//b.cpp
int initB() { return 19; }
int foo<0>::s_member = initB();
static int maintest()
{
foo<0> myfoo;
}
This does to compile, but only one of the definition are actually executed (some simple tests suggests that if a.cpp is added to the solution first then initA() is executed, and if b.cpp is added first then initB() is executed...
- petter
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|