In a .cpp file, is there any difference/preference either way?
// file scope outside any namespace
using X::SomeClass;
typedef SomeClass::Buffer MyBuf;
v/s
namespace { // anonymous
using X::SomeClass;
typedef SomeClass::Buffer MyBuf;
}
I would say that the second usage is rather uncommon, at least in the code that I've seen so far (and I've seen quite a lot C++ of code). Could you explain what the reasoning behind the second technique is?
You will normally use an anonymous namespace in a C++ implementation file to achieve the same thing that 'static' would do in C (or C++, but we'll gloss over that), namely restricting the visibility of the symbols to the current translation unit. The typedef doesn't actually produce symbols that are exported for the linker to see as they don't create anything 'concrete' in the sense of anything concrete that you could link against.
My recommendation? I'd go with the first notation. The second one adds an unnecessary complication and in my opinion, doesn't buy you anything.
There is not much point in placing typedefs in anonymous namespaces. The main use for anonymous namespaces is to avoid symbol collision between translation units by placing definitions with external linkage in them.
Related
Imagine I've got the following files:
simulate.h:
#ifndef SIMULATE_H
#define SIMULATE_H
#include "my_data_type.h"
MyDataType Simulate ();
#endif
simulate.cpp:
#include "simulate.h"
// include lots of other things
// define lots of functions and new classes to solve sub-problems
// finally we define the "Simulate" function, which is the **only** thing we want to export.
Now, imagine that we have lots of header/cpp files pairs like above (with a tonne of functions/data types that aren't required outside of the cpp files).
Am I right in thinking that this creates unnecessary overhead for both the compiler and the linker?
As I understand it, the compiler can't know what won't be used by other object files, so this would create more bloated .o files and thereby slow down the linker, is that right?
I know that modules solves a lot of these problems in c++20, but is there some standard way around it in c++17?
I can think of one way that would seem to communicate to the compiler that the introduced functions/data types are not going to be reused: wrap them up in a class, put everything in the private section and expose only one method to the public. However, this is super hacky and ugly.
As I understand it, the compiler can't know what won't be used by other object files, so this would create more bloated .obj files and thereby slow down the linker, is that right?
Broadly speaking... no.
The code has to be in the .o files, because the code you do "export" uses it. Any code transitively used by the executable has to get compiled and stored in some object file. So it's going to have to be somewhere, and the compiler will have to read it and store it in the executable.
As for whether it slows down linkers, they're pretty good about finding the specific code they're looking for. I mean yes, some compilers may load the whole file into memory, so a bigger .o will take longer to load. But again, your "exported" function uses that code, so it still matters.
As Jarod42 pointed out in the comments, we can used unnamed/anonymous namespaces, whose contents are unreachable from other translation units (N3797: 7.3.1.1):
An unnamed-namespace-definition behaves as if it were replaced
by
inline /*opt*/ namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }
where inline appears if and only if it appears in the
unnamed-namespace-definition, all occurrences of unique in a
translation unit are replaced by the same identifier, and this
identifier differs from all other identifiers in the entire program.
So we can use this to tell the compiler what's local to our translation unit:
namespace // Sub-problem stuff:
{
// ... classes
// ... functions
}
// Export stuff:
// ... classes
// ... functions
This way the compiler is only bound to the correct behaviour of the "exports", so can do things like remove some of the sub-problem functions that have been inlined.
As answered in this question, I learnt that the static keyword to the function means it can only be seen from the functions in that file. I think unnamed namespace can be used for the same purpose.
However, usually, implementation and header files are separated. So, it seems to me that a programmer can hide all the "private stuff" inside the implementation file by not writing the declaration of such private stuff in the header file.
Considering above, when are static and unnamed namespaces helpful? The only case I can come up with is where multiple implementation files correspond to a single header file.
Keeping a definition in implementation file does not make it private in any sense. Any other header or implementation file can declare that function and use it. It's not always a bad thing - I used parts of private implementations of libraries when I really needed it (but I do not recommend doing that).
The worse part of having such not-so-private implementation is its potential for One Definition Rule violation. ODR states that every* function or variable must have exactly one definition in the whole program. If there is more than one definition, behaviour is undefined**.
This means that when you have your not-so-private implementation in your file and nobody knows about it, they can unknowingly write a function with the same name and arguments and get an ODR violation.
It would be a good practice to use static or anonymous namespace for all free functions that should be limited to a single file. Functions that need to be used from other files cannot use this strategy, so to limit the risk of ODR violations you should use descriptive names and perhaps (named) namespaces. Just make sure you don't overuse namespaces.
Note: using anonymous namespaces doesn't make sense in header files. Anonymous namespace limits the scope of its content to the translation unit in which it exists, but header files are copied and pasted into (potentially) multiple TUs. The one use of anonymous namespaces is in header-only libraries, as described in this question - it allows to create global objects in header file without ODR violation (but at a cost that each TU has its own copy of that variable).
*except for template functions, inline functions, functions defined in class definition and a couple more. Even then, all definitions must be exactly the same.
**When I encountered it once, linker used random definition, whichever it saw at that moment. Hilarity and long debugging sessions ensued.
I've heard it asserted that the use of unnamed namespaces in C++ to define functions and ensure that they cannot be called from outside the compilation unit in which they are defined is not good in very large code environments because they cause the symbol table to grow unnecessarily large by including entries to these symbols in the automatically generated namespaces that the C++ compiler provides when unnamed.
namespace {
// This function can only be accessed from hear to the end of
// any compilation unit that includes it.
void functionPerhapsInsertedIntoSymbolTable() {
return;
}
}
This is perhaps given that the above is supposed to be the same as doing the following:
namespace randomlyGenerateNameHereNotCollidingWithAnyExistingNames {
// This function can only be accessed from hear to the end of
// any compilation unit that includes it.
void functionPerhapsInsertedIntoSymbolTable() {
return;
}
}
using randomlyGenerateNameHereNotCollidingWithAnyExistingNames;
However, is it really that simple, is the compiler required to make a symbol table entry for symbols in the generated namespace name?
Instead, in such situations, I heard it suggested to use a static declaration:
// This function can only be accessed from hear to the end of
// any compilation unit that includes it.
static void functionNotInsertedIntoSymbolTable() {
return;
}
Is it true that using a static declaration before a function instead of placing it in an unnamed namespace has the same effect of making the function inaccessible outside the compilation unit in which it is defined? Is there any difference between these two approaches other than potentially not causing the symbol table to grow?
Is the issue with symbol table bloat due to unnamed namespaces just a bug in some implementations of C++ or is the compiler somehow required by the standard to create entries for such functions? If this bloat is considered a bug, are there known compilers for which this is not an issue?
Is it true that using a static declaration before a function instead of placing it in an unnamed namespace has the same effect of making the function inaccessible outside the compilation unit in which it is defined?
Yes.
Namespace-static was deprecated in C++03 in favour of unnamed namespaces, but in fact un-deprecated for C++11 when everybody realised that they are just the same thing and there was no purpose to the deprecation.
Is there any difference between these two approaches
No, not really. There may be some minor subtleties with name lookup due to the use of a namespace, but I can't think of any right now.
other than potentially not causing the symbol table to grow?
Since this is a language-lawyer question with no evident practical problem to solve, I am obliged to point out that the C++ language has no concept of a symbol table, and thus no indication of this effect.
It's also not going to have any noticeable effect until you have tens of thousands of unnamed namespaces; do you?
The reason for the unnamed namespace and deprecation of namespace level static is the ill-fated export keyword.
Everything an exported template relies on has to be link-accessible at the points of instantiation, which are most likely in different source files. The unnamed namespace allowed the 'privatization' aspect of static while still preserving linkage for exported templates.
Now that export has been removed in C++2011, I'm pretty sure the external linkage requirement for the unnamed namespace has been removed, and it now behaves exactly like namespace level static. Someone more familiar with the standard can confirm/refute this.
I have been reading articles about unnamed namespaces the whole day, most articles explained when you should use unnamed namespaces over the static keyword. But I am still left with one big question when is it appropriate to use static? After all it is not completely deprecated, what about header files with static functions should I put them into unnamed namespaces now?
#ifndef HEADER_H
#define HEADER_H
static int func() {
...
}
// versus:
namespace {
int func() {
...
}
};
#endif // HEADER_H
Or what about static member functions?
Greetings
The precise wording of the standard is:
The use of the static keyword is deprecated when declaring objects in namespace scope.
Functions in a header file should be inline rather than static or in an unnamed namespace. inline means you will only end up with at most one copy of the function in your program, while the other methods will give you a separate copy from each file that includes the header. As well as bloat, this could give incorrect behaviour if the function contains function-static data. (EDIT: unless the function is supposed to have different definitions in different compilation units, perhaps due to different preprocessor macros that are defined before including the header file. In that case the best approach is not to include it at all, but rather to bury it in an unmarked grave with a stake through its unholy heart.)
Data objects, apart from constants, usually shouldn't be defined in header files at all, only declared extern.
Static member functions are a different kettle of fish, and you have to use static there as there is no other way to declare them. That usage isn't deprecated, since it isn't in namespace scope.
UPDATE: C++11 has removed the deprecation, so there's no longer any particular reason to prefer unnamed namespaces over static. But you still shouldn't use either in a header file unless you're doing something weird.
There is no advantage of static in namespace scope over unnamed namespaces which I know of. Use unnamed namespaces, as in the example above. Actually in the example above I can't see why is static or unnamed namespace necessary. Maybe inline?
And static member functions have nothing to do with static at namespace scope. Static member functions (and nonfunction members) are still valid.
In a header file there's usually no point in specifying internal linkage, or using an anonymous namespace.
In a separately compiled implementation file you can use static or an anonymous namespace to avoid linkage level name collisions or client code relying on implementation details. An anonymous namespace lets you have external linkage, which is required for template parameters, and it also supports class definitions. But in the end it's just a question of practicality and personal preference, on a case by case basis.
static for a member function has nothing to do with linkage specification. A static member function has external linkage anyway.
static can be preferable if you are using some tools. It also behaves a bit better with auto indent functionality in most text editors. It's a bit sad, when you have to avoid using something useful because it doesn't work with tools that should really support it, but I promise you'll get over it.
An example question that gives some hint of potential pain in the debugging department:
Viewing namespaced global variables in Visual Studio debugger?
You probably won't have to look very hard to find more problems, but the debugger issues were enough to make me entirely give up on namespaces, to the maximum extent possible, so I've never looked any further.
My personal recommendation is that for code that will be around for less than forever, one might as well go with static. Does effectively the same thing as an unnamed namespace, but, averaged out over all tools, it is better supported. In theory, one day it will disappear completely, but I'm happy to publicly admit that I'm certain that day will never actually come to pass. And in the mean time, you are saving yourself some pain.
I am thinking it is a best practice to declare them as static, as it makes them invisible outside of the module.
What are your thoughts on this?
For C++, a better than static is to put it in an unnamed (anonymous) namespace. This is the preferred way to prevent pollution of the Global namespace.
namespace {
void myLocalFunction() {
// stuff
}
}
If it is truly an function which is internal only to that .c file, then yes. It should help avoid polluting the global namespace. Also, I think that the compiler is able to do some optimizations with calling conventions if the function is static since it knowns no other source file needs to know how to call it. This only really applies to c because as others have noted, c++ has namespaces to address this issue.
There was a lot about implementation details and not too much about concept.
Limiting the scope of variable/function etc.. is a good practice indeed. This is a basic concept of object oriented design - you want keep private as private. This way your interface is cleaner and code maintenance is easier. And you will not find one day that changing something that you considered as private broke compilation because somebody in another part of project liked your function and decided to use it.
In C, I make everything - functions and variables - static at file scope until I can demonstrate they're necessary outside the file. I'll make things static within a function if only that function will use them and they are not too huge. Basically, if the declaration is bigger than the rest of the function, I may put the declaration outside the function. And, of course, there's a header for the public services provided by a source file.
Agreed. As a consequence, the prototypes for the static functions must go at the top of the .c file, not in the .h file.
In C++, you should use an anonymous namespace, like so:
// foo.cpp
namespace
{
class Core { ... };
void InternalFandango(Core *);
}
void SomeGloballyVisibleFunction()
{
InternalFandango(&core);
}
Advantage: this is applicable to struct / class declarations, too.
In C, just mark the functions "static". There's nothing against using "static" in C++, too, but I've learnt to prefer the namespace, as it is one single concept that works for all declarations.
I think C and C++ have different constraints concerning static: in C you don't have namespaces and .c files are your modules, so it is really really important to put all non-public functions as static to prevent errors!
About the only potentially useful property I can think of for this use of "static" in C++, that anonymous namespaces don't provide, is that there's a warning in GCC you can switch on for unused static functions (a form of dead code). You don't get that for unused functions in anonymous namespaces, so in the unlikely event that you want the compiler to tell you when you stop using the function, do it that way.
In C code, make your functions static by default. Only make non-static functions and .h declarations for functions that will be needed by other modules.
In C++ code, put those functions that are local to the file into an anonymous namespace and make them static. In the GNU compiler at least, this will result in the best and smallest code, because no function will be written if all uses are inlined. If you intend it to be inlined, then of course marking it inline is even better than static.
I do not know why g++ writes the uncalled function bodies that are in anonymous namespaces into the output at all, but it does. Functions with hidden visibility seem to show up as well; marked as hidden symbols, but still producing unused code blocks in the object file. GCC probably doesn't understand that the code isn't needed in those cases. Or I am missing something, always possible.
If you're using GCC, then you should take a look at the visibility flag (see http://gcc.gnu.org/wiki/Visibility for a full discussion).
It'll hide symbols completely as opposed to marking them unreachable. That reduces the symbol table, and helps decrease link times.
Not only that, it opens the door for more inlining, if that's what you're after.
If by 'module' you just mean a CPP file, you could just place the declaration and the definition right in the CPP file.
In C++, you'd declare the function private like this:
class MyClass
{
public:
void publiclyAccessibleFunction();
private:
void onlyAccesibleFromWithinTheClass();
int some_member_parameter;
};
Note the onlyAccesibleFromWithinTheClass() function.