quote:Original post by tangentz
Not if the compiler is "faulty". Shared() is copied as
many times as it is inlined, causing multiple instances
of the static variables to be present. See MEC++. The only
way to be sure is to make Shared() non-inline.
I agree. The 1996 C++ standard corrects this behaviour. If it was a pre 1996 compiler, I would expect it to have this problem. But VC++6 ? (Well, I''m won''t too surprised if it has that bug)
quote:
Sorry, but this is wrong. A static function exists ONLY
in the translation unit (CPP) where it is compiled in. You
can''t even extern and use it, because it has internal linkage.
Only ONE instance of this is present.
I am assuming you put it in a header file like the inlined version.
Take a look at this code( VC++ 6sp5 - full optimizations, inlined whereever suitable)
// %%%%%% C.h %%%%%#include <iostream>class C{public: static void Method();};inline void C::Method(){ static int count; std::cout << ++count << "\n";}//%%%%% another.cpp %%%%%#include "C.h"void F(){ C::Method(); // breakpoint}//%%%%% main.cpp %%%%%%#include "C.h"extern void F();int main(){ C::Method(); F(); // breakpoint return 0;}
The output printed is 1,2. As expected.
Looking at the disassembly
//%%%%% main.cpp %%%%%
5: int main()
6: {
00401000 mov eax,[count (0041ef84)]
00401005 push offset string "\n" (0041b070)
0040100A inc eax
0040100B mov ecx,offset std::cout (0041eb38)
00401010 push eax
00401011 mov [count (0041ef84)],eax
00401016 call std::basic_ostream >::operator<< (00401030)
0040101B push eax
0040101C call std::operator<< (00401490)
00401021 add esp,8
7: C::Method();
8:
9: F();
00401024 call F (00403970)
10:
11: return 0;
00401029 xor eax,eax
12: }
0040102B ret
// %%%%% another.cpp %%%%%
3: void F()
4: {
00403970 mov eax,[count (0041ef84)]
00403975 push offset string "\n" (0041b070)
0040397A inc eax
0040397B mov ecx,offset std::cout (0041eb38)
00403980 push eax
00403981 mov [count (0041ef84)],eax
00403986 call std::basic_ostream >::operator<< (00401030)
0040398B push eax
0040398C call std::operator<< (00401490)
00403991 add esp,8
5: C::Method();
6: }
00403994 ret
C::Method() looks inlined to me and it produces the correct results.
You can try it with a inlined non member function and it still shows the correct results.
//%%%% C.h %%%#include <iostream>// if this is static, then it is a totally different storyinline void C(){ static int count; std::cout << ++count << "\n";}//%%%% another.cpp %%%%#include "C.h"void F(){ C();}//%%%%% main.cpp %%%%#include "C.h"extern void F();int main(){ C(); F(); return 0;}
[/source]