Given that yonder longish list of Things That Go Wrong In LyX is hard to
keep in mind while aging I thought I might share this little gem with
you.

Bad news from the ivory tower part II (Anon namespace vs 'static'):

Compare

  namespace { int fooX() { return X; } }

with

  static int fooX() { return X; }


Looks innocent?


Result:


[EMAIL PROTECTED]:/tmp > perl -e '$n=10000; print "static int foo$_() { return
$_; }\n" foreach 1..$n; print "int foo() { return 0"; print "+foo$_()\n"
foreach 1..$n;  print ";}\n";' > 1.cpp ; /usr/bin/g++ -c 1.cpp  ; l 1.o

-rw-r--r-- 1 andre users 449606 Aug 27 23:56 1.o

[EMAIL PROTECTED]:/tmp > perl -e '$n=10000; print "namespace { int foo$_() {
return $_; } } \n" foreach 1..$n; print "int foo() { return 0"; print
"+foo$_()\n" foreach 1..$n;  print ";}\n";' > 1.cpp ;  /usr/bin/g++
-c 1.cpp  ; l 1.o

-rw-r--r-- 1 andre users 909652 Aug 27 23:56 1.o

So the namespace version is twice as big as good old 'static'. Not
surprising, the things anonymous namespace is not really anonymous, but
rather a namespace with a random-but-hopefully-globally-unique name. This
name takes space.

Compile time is the same without optimization.

And now a bit more fun by adding optimization (note s/10000/1000, and -O2):

[EMAIL PROTECTED]:/tmp > perl -e '$n=1000; print "namespace { int foo$_() {
return $_; } } \n" foreach 1..$n; print "int foo() { return 0"; print
"+foo$_()\n" foreach 1..$n;  print ";}\n";' > 1.cpp ; time /usr/bin/g++
-O2 -c 1.cpp  ; l 1.o

real    0m3.927s
user    0m3.568s
sys     0m0.060s
-rw-r--r-- 1 andre users 106476 Aug 28 00:01 1.o
[EMAIL PROTECTED]:/tmp > perl -e '$n=1000; print "static int foo$_() { return
$_; }\n" foreach 1..$n; print "int foo() { return 0"; print "+foo$_()\n"
foreach 1..$n;  print ";}\n";' > 1.cpp ; time /usr/bin/g++ -O2 -c 1.cpp
; l 1.o

real    0m0.549s
user    0m0.512s
sys     0m0.028s
-rw-r--r-- 1 andre users 728 Aug 28 00:02 1.o

Anon namespace loses by a factor of 7 in time and 146 in space.

Surprised?

Hardly.

And no, that's not a 'compiler problem'. The compiler behaves as defined
in the Holy Standard: Functions in the anon namespace have _external_
linkage even if they are not (well, not 'really' at least) accessible
from the outside.  On the other hand, static functions have, well,
static linkage. They have to be really invisible to the outside and
therefore can optimized away completely.

Of course it's a somewhat pathological example and we won't suddenly
compile 7 times faster within 1/146 diskspace when we kick anon
namespaces out. But the direction is clear...

So anybody who remembers the reasons to use the anon namespace (for
_functions_)? [Rhetorical question...]

Andre'


Reply via email to