help: static vs namespace?

A

ark

Hi,
If I got it right, C++ deprecates using 'static' keyword for internal
linkage in favor of a namespace.
I don't understand the equivalence though: namespace assignment does not
mechanically guarantee that the name won't be referenced (with proper scope
resolution) in another translation unit. So the compiler must treat the
namespaced function as if it had external linkage. Thus, it must miss on
several optimizations available for static functions, which may be possible
based on study of the use of the function. (Typical: partial
prologue/epilogue generation, automatic inlining and such, which in turn
allows further register optimization in the callers.)

E.g.,
static double foo(int x) { return (1-x*x*(x+1))/(double)(1+x*x); }
double bar(int y) { return (y<0)?foo(3):foo(5); }

In this case foo can be translated into something like
static double foo(int x)
{ return (x==3)?(1-3*3*4)/(double(10):(1-5*5*6)/(double)(26); }

which is just a choice between two numbers.

Is this deprecation a concious sacrifice? If so, to what?

Thanks,
Ark
 
V

Victor Bazarov

ark said:
If I got it right, C++ deprecates using 'static' keyword for internal
linkage in favor of a namespace.

AFAIK, you got it right.
I don't understand the equivalence though: namespace assignment does not
mechanically guarantee that the name won't be referenced (with proper scope
resolution) in another translation unit. So the compiler must treat the
namespaced function as if it had external linkage.

That's the difference between the two: the namespace one does have
external linkage. My question would be, "so what?"
Thus, it must miss on
several optimizations available for static functions, which may be possible
based on study of the use of the function. (Typical: partial
prologue/epilogue generation, automatic inlining and such, which in turn
allows further register optimization in the callers.)

Are you implying that those are impossible for functions in the
anonymous namespace? Why?
E.g.,
static double foo(int x) { return (1-x*x*(x+1))/(double)(1+x*x); }
double bar(int y) { return (y<0)?foo(3):foo(5); }

In this case foo can be translated into something like
static double foo(int x)
{ return (x==3)?(1-3*3*4)/(double(10):(1-5*5*6)/(double)(26); }

which is just a choice between two numbers.

Is this deprecation a concious sacrifice? If so, to what?

Why would it be a sacrifice? The compiler knows that the function is
in the unnamed namespace, it can do all the optimisations it wants, no?

Victor
 
I

Ivan Vecerina

Hi Ark,

ark said:
If I got it right, C++ deprecates using 'static' keyword for internal
linkage in favor of a namespace.
In favor of *anonymous* namespaces -- which is basically a namespace
with a new unique name for each translation unit (each file compiled).
I don't understand the equivalence though: namespace assignment does not
mechanically guarantee that the name won't be referenced (with proper scope
resolution) in another translation unit.
The guarantee *is* provided for anonymous namespaces. The compiler may
rely on this, and perform the same optimisations as if the function
had internal linkage.
So the compiler must treat the
namespaced function as if it had external linkage. Thus, it must miss on
several optimizations available [...]

Is this deprecation a concious sacrifice? If so, to what?
By design, an anonymous namespace is a replacement for static globals.
The only difference is that a linkage name will be generated
by the compiler.
The main advantage of this is that this linkage name can be used
for template instanciation.

However, this added linkage name does have a cost on typical platforms,
in terms of the size of the object file. So using 'static' could still
be a legitimate way to reduce this overhead.
A while ago, this lead to a debate about whether 'static' should
really be deprecated... which in turn lead to a discussion about
the meaning of 'deprecated'...
groups.google.com/groups?threadm=aledo8%24k0g%241%40localhost.localdomain


I hope this helps...

Cheers,
 
G

Gianni Mariani

Ivan Vecerina wrote:

.....
The main advantage of this is that this linkage name can be used
for template instanciation.

I really don't get this comment. Please explain.
 
K

Kevin Goodsell

ark said:
Hi,
If I got it right, C++ deprecates using 'static' keyword for internal
linkage in favor of a namespace.

....in favor of an anonymous namespace.

namespace
{

int some_var;

}


// some_var can be accessed in functions
// that appear after the namespace
// but only in this source file.

Sorry, didn't read the rest, gotta run.

-Kevin
 
U

Unforgiven

ark said:
Hi,
If I got it right, C++ deprecates using 'static' keyword for internal
linkage in favor of a namespace.

In addition to what already has been said, I also recommend the column by
Robert Schmidt on unnamed namespaces:
http://msdn.microsoft.com/library/en-us/dndeepc/html/deep04062000.asp

In fact, I recommend all of Schmidt's columns. Never mind the fact he writes
(or wrote actually, unfortunately he doesn't anymore) on MSDN, 99% of his
talk is about ISO C++, and where Visual C++ is mentioned it's often only to
point out where it lacks in conformance.
 
I

Ivan Vecerina

Gianni Mariani said:
Ivan Vecerina wrote: ....

I really don't get this comment. Please explain.

When a template class or function is instantiated, the name or
value of its template parameters is used to generate a linkage
name for the template instance.
This name is essential to the linker's job, as it identifies
all object references that it needs to process. Also, it will
typically allow the linker to merge duplicate instances of a
template.

Template parameters can be of 'class' kind, in which case
the name of the class for which the template is instantiated
is embedded in the template's instantiation name;
But a template parameter can also be a pointer to a function
or a global variable -- with external linkage -- in which case
the name of the global/function is embedded in the name
of the template instance.

Well, here's an example that should clarify this:

class ClassA {};
class ClassB {};

ClassA a0,a1; static ClassA aS;
ClassB b0;

template<class T>
void clsF()
{ }

template<ClassA* ref>
void glbF()
{ }

int main()
{
clsF<ClassA>(); //link name: ?clsF@?$@VClassA@@@@YAXXZ
clsF<ClassB>(); //link name: ?clsF@?$@VClassB@@@@YAXXZ
//Note that name of class is here: ^^^^^^

glbF<&a0>(); //link name: ?glbF@?$@$1?a0@@3VClassA@@A@@YAXXZ
glbF<&a1>(); //link name: ?glbF@?$@$1?a1@@3VClassA@@A@@YAXXZ
//Note that name of global var used: ^^

class LocalClass {};
clsF<LocalClass>(); // ILLEGAL: LocalClass has no linkage

glbF<&aS>(); // ILLEGAL: aS has internal linkage
}

The name of the functions generated (template instances) used
by some compiler has been included. Note how the name of the
template type or global parameter has been embedded in the
name of the generated function.

In the last two function calls, how would the compiler
generate a name for the template instance ?
(admittedly, there are ways a unique name could be picked,
but not according to the current C++ standard).


If you want more info, googling for "name mangling" and
"template" should bring some usable links...



hth,
 
H

Hafiz Abid Qadeer

ark said:
Hi,
If I got it right, C++ deprecates using 'static' keyword for internal
linkage in favor of a namespace.
I don't understand the equivalence though: namespace assignment does not
mechanically guarantee that the name won't be referenced (with proper scope
resolution) in another translation unit. So the compiler must treat the
namespaced function as if it had external linkage. Thus, it must miss on
several optimizations available for static functions, which may be possible
based on study of the use of the function. (Typical: partial
prologue/epilogue generation, automatic inlining and such, which in turn
allows further register optimization in the callers.)

E.g.,
static double foo(int x) { return (1-x*x*(x+1))/(double)(1+x*x); }
double bar(int y) { return (y<0)?foo(3):foo(5); }

In this case foo can be translated into something like
static double foo(int x)
{ return (x==3)?(1-3*3*4)/(double(10):(1-5*5*6)/(double)(26); }

which is just a choice between two numbers.

Is this deprecation a concious sacrifice? If so, to what?

Thanks,
Ark


There is a concept of unnamed namespaces. If you use unnamed
namespaces, there is generally no way to access its members from
different translation unit. in C++ programming language section
8.2.5.1 Stroustrup writes" there is no way of naming a member of an
unnamed namespace from another translation unit." Hope that helps
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top