Monday, April 7, 2008

Static at namespace scope deprecated

Scope

The primary objective of the post is discuss the deprecated declaration of static names at a namespace scope, its alternative and any caveats to the same.

Introduction

The question that arises in the naive mind is: What did we achieve by declaring a name in the declarative region of a namespace with a static keyword? The the answer that follows after some introspection is: Of course limiting the scope of the name from its point of declaration in the namespace to the end of the translation unit/ the declarative region of the namespace.

If that were the case then, what are we losing by such a language feature that it needs to be deprecated? Are there some alternatives to the same? Is the 'thing' altogether gone...

These are some of the questions that i'll try to answer in the discussion that follows.

Why deprecated?

The use of the keyword static to limit the scope of external variables is deprecated for declaring objects in namespace scope. It is known that static in the declaration of such objects means that the name has internal linkage, hence limiting the scope to the translation unit in which it is defined. This however prevents the usage of the name as a non type template argument for a template instantiation. 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. The internal linkage for the static object prevents this. Just to give an example consider the code snippet below.

template<typename T, int SIZE>

class Array

{

private:

T *mArray;

enum { kSize = SIZE };

};



const int gSize = 5;

Array<int, gSize> IntegerArrayGSize; // Valid



static int sSize = 6;

Array<int, sSize> IntegerArraySSize; // C2970 cannot use static variable in templates
One of the argument that favored the deprecating of the feature is the introduction of the namespaces in C++. A solution for hiding the name from other translation units is to declare such names inside an unnamed namespace. Though these names are having external linkage but they still cannot be referred to easily in other units because of unique mangled name generated for such a namespace. This makes them a candidate for template instatntiation as well, which was missing with the static objects.

Gone forever?

Doesn't seem to be feasible in distant future :). There might be reasons to still carry on with the feature. Go on and read further...

. Even the Standard doesn't follow it's own guidelines. To cite the Standard 9.5.3 "Anonymous unions declared in a named namespace or the global namespace shall be declared static".

. It implicitly declares quoted literals as static.

. Static is the key for its compatibility with C which lacked namespaces, and we all know we cannot introduce the same in C.

. Because templates may be instantiated on members of unnamed namespaces, some compilation systems may place such symbols in the global linker space, which could place a significant burden on the linker. Without static, programmers have no mechanism to avoid the burden.

Conclusion

The use of static as of now stands deprecated as per the C++ standard and the alternative suggested for the purpose is to define the member inside an unnamed namespace.

References

[1] informIT - C++ Reference Guide (Deprecated Features)
[2] C++ Standard
[3] C++ Standard core language issues closed

What people said... (0)