difference between static functions in C++ - c++

Can anybody explain difference between static function defined within class and static function declared e.g. in file.hpp and defined in file.cpp (I can only use this static function within this file ?

Can anybody explain difference between static function defined within class
That means the function is class-wide, and doesn't need to operate on a particular object. In other words, for that function there is no this.
and static function declared e.g. in file.hpp and defined in file.cpp (I can only use this static function within this file ?
That means that that function does not have external linkage, which means other compilation units (i.e. object files) cannot link to it, because it's not in the symbol table.
Thanks for your reply but could you explain why other compilation units cannot link to it ?
First, some terms. Technically, the compiler is just the part that generates object code from source code. The linker later takes a set of object files and "links" them to make the final program.
To make this work, the compiler generates a "symbol table" and puts it in the object file along with the compiled code. This symbol table lists both the symbols for the global variables and functions in the file, as well as the external symbols that code needs to be linked to in order to work.
The linker's job is to read all the object files and match symbols needed by each object file to symbols provided by other object files. If everything is successful, and there aren't any unresolved needed symbols, the link succeeds and you get your program.
What static on a function or global does is simply tell the compiler to not put that symbol in the object file's symbol table. Nothing else; that symbol is still perfectly usable within that same source file. The linker simply never sees the symbol, and thus cannot link anything to it.
Class members cannot be "disappeared" in this manner, so static has a different meaning in the context of a class. (This recycling of the keyword was probably done to avoid adding another reserved word to the language. BTW, Objective-C solved this same problem in a different manner, using the + and - tokens.)
(And static can have yet another meaning when applied to variables declared inside functions or methods, as Mike points out below. In that case it's basically a global variable, but private to the function.)
Could you also explain why inline functions are implicitly defined as static ?
Since inline functions do not exist as independent pieces of code (they are instead merged "in line" into the calling function), they cannot have symbol table entries (there's nothing to link to).

Please refer to this link
A static variable inside a function keeps its value between invocations.
In C++, however, static is also used to define class attributes (shared between all objects of the same class) and methods. In C there are no classes, so this feature is irrelevant.

There is no difference between a static function defined in the global scope, no matter if it's in a header file or in a source file. Unless the header file isn't included anywhere, when the functions in it is never really defined anywhere.
Then phrase you need to learn when talking about static (non-member) functions is translation unit. A translation unit is a source file and all header files included in that source file, after the preprocessor have processed the file and is the actual input to the compiler. A static function is local to the translation unit, which is why there is no difference if it's defined in the source file or a header file.
You can also use an anonymous namespace to define functions, and they will be local to just the translation unit the anonymous namespace is in.
Also note that functions defined as inline are implicitly defined as static as well.
A static member function is part of the class, and can access static member variables without scope prefix. They do of course have to prefixed with the scope of the class to be called. The difference between a static member function and a non-static member function is that static member functions are not part of any specific instance of the class, and so have no this pointer. If you want to access a specific class instances member variable, you have to pass the instance to the static member function through an argument.

Related

Linker removing static initialiser [duplicate]

I am working on a factory that will have types added to them, however, if the class is not explicitly instiated in the .exe that is exectured (compile-time), then the type is not added to the factory. This is due to the fact that the static call is some how not being made. Does anyone have any suggestions on how to fix this? Below is five very small files that I am putting into a lib, then an .exe will call this lib. If there is any suggestions on how I can get this to work, or maybe a better design pattern, please let me know. Here is basically what I am looking for
1) A factory that can take in types
2) Auto registration to go in the classes .cpp file, any and all registration code should go in the class .cpp (for the example below, RandomClass.cpp) and no other files.
BaseClass.h : http://codepad.org/zGRZvIZf
RandomClass.h : http://codepad.org/rqIZ1atp
RandomClass.cpp : http://codepad.org/WqnQDWQd
TemplateFactory.h : http://codepad.org/94YfusgC
TemplateFactory.cpp : http://codepad.org/Hc2tSfzZ
When you are linking with a static library, you are in fact extracting from it the object files which provide symbols which are currently used but not defined. In the pattern that you are using, there is probably no undefined symbols provided by the object file which contains the static variable which triggers registration.
Solutions:
use explicit registration
have somehow an undefined symbol provided by the compilation unit
use the linker arguments to add your static variables as a undefined symbols
something useful, but this is often not natural
a dummy one, well it is not natural if it is provided by the main program, as a linker argument it main be easier than using the mangled name of the static variable
use a linker argument stating that all the objects of a library have to be included
dynamic libraries are fully imported, thus don't have that problem
As a general rule of thumb, an application do not include static or global variables from a library unless they are implicitly or explicitly used by the application.
There are hundred different ways this can be refactored. One method could be to place the static variable inside function, and make sure the function is called.
To expand on one of #AProgrammer's excellent suggestions, here is a portable way to guarantee the calling program will reference at least one symbol from the library.
In the library code declare a global function that returns an int.
int make_sure_compilation_unit_referenced() { return 0; }
Then in the header for the library declare a static variable that is initialized by calling the global function:
extern int make_sure_compilation_unit_referenced();
static int never_actually_used = make_sure_compilation_unit_referenced();
Every compilation unit that includes the header will have a static variable that needs to be initialized by calling a (useless) function in the library.
This is made a little cleaner if your library has its own namespace encapsulating both of the definitions, then there's less chance of name collisions between the bogus function in your library with other libraries, or of the static variable with other variables in the compilation unit(s) that include the header.

Static functions outside classes

Could someone tell me what's the purpose of declaring static functions outside classes? What's the difference between this 2? Are there any benefits for using static in this situation?
static void someRandomFunction();
int main()
{
someRandomFunction();
return 0;
}
and
void someRandomFunction();
int main()
{
someRandomFunction();
return 0;
}
At namespace scope, static gives a name internal linkage, meaning that it is only accessible within the translation unit that contains the definition. Without static, it has external linkage, and is accessible in any translation unit.
So you'd use static (or, alternatively, an unnamed namespace) when writing a function that's only intended for use within this unit; the internal linkage means that other units can define different functions with the same name without causing naming conflicts.
Non-static functions (and global names in general) are better declared in a header, to make sure that every translation unit that uses them gets the same declaration.
The static keyword on global functions or variables limits the visibility and linkage scope of the function or variable to the current translation unit.
That means that for a function, it can only be called from the current source file, and not from other source files.
A static function remains visible only in file scope. This is a C feature.
The recommended way to do it in C++ is using an anonymous namespace, as in:
namespace // no name, i.e. anonymous
{
void someRandomFunction();
}
int main()
{
someRandomFunction(); // visible only within this file.
return 0;
}
Note that the function body also has to be declared somewhere within the same file since the linker will not try to find it in other (external) translation units.
So void someRandomFunction(); is really a forward declaration for a function that is defined elsewhere in the same file (i.e. in the same translation unit).
If the function is actually called, you will get a linking error unless the function body is defined in the same file.
(The more pedantic technical term is actually not file but translation-unit since the body might be in an #includeed header do not in the actual file per-se. )
static void someRandomFunction();
This has to be used within same compilation unit (source file) and outside that compilation unit, not available for use.
Whereas, if you have
void someRandomFunction();
with one definition acrosss the program, the function can be used by any compilation unit globally across the program
Static methods and static functions are entirely different things.
Static methods are methods of a class instead of an instance (which you already know, as it seems).
Static functions, on the other hand, are function which are available only in the module they are defined in. They are not exported and cannot be put in a header file and used in another c file. This way you can write different functions sharing the same name, and also the compiler may optimize your code more thoroughly by inlining the function, knowing that no other file is dependant on it.
static tells the compiler not add the function to the symbol table for the object file. This effectively means that the linker is unable to find the function which in turn means you can only use the function directly in the current compilation unit. You can however call static functions from another compilation unit if this is done through a function pointer.

Which object file contains the following static templatized "member variable"?

Say I have the following template class with a static member function that itself instantiates a static variable (which is functionally a static member variable instantiated the first time its containing routine is called):
template <typename T>
struct foo
{
static int& mystatic()
{
static int value;
return value;
}
};
If I use foo<T> in multiple translation units for some T, into which object file does the compiler put foo<T>::mystatic::value? How is this apparent duplication/conflict resolved at link time?
You do understand that the your function mystatic is a function with external linkage? Which means that the very same conflict exists between multiple definitions of mystatic made in different translation units. Also, exactly the same issue can arise without templates: ordinary inline functions with external linkage defined in header files can produce the same apparent multiple definition conflict (and the same issue with a local static variable can be reproduced there as well).
In order to resolve such conflicts, all such symbols are labeled by the compiler in some implementation-dependent way. By doing this the compiler communicates to the linker the fact that these symbols can legally end up being defined multiple times. For example, one known implementation puts such symbols into a separate section of object file (sometimes called "COMDAT" section). Other implementations might label such symbols in some other way. When the linker discovers such symbols in multiple object files, instead of reporting a multiple definition error, it chooses one and only one of each identical symbol and uses it throughout the entire program. The other copies of each such symbol are discarded by the linker.
One typical consequence of this approach is that your local static variable value will have to be included as an external symbol into each object file, despite the fact that it has no linkage from the language point of view. The name of the symbol will usually be composed of the function name mystatic and variable name value and some other mangling.
In other words, the compiler proper puts both the definition of mystatic and the variable value into all independent object files that use the member function. The linker will later make sure that only one mystatic and only one value will exist in the linked program. There's probably no way to determine, which original object file supplied the surviving copy (if such distinction even makes sense).

Difference between an inline function and static inline function

Can anybody tell me what the difference is between an inline function and static inline function?
In which cases should I prefer static inline over inline?
I am asking this question because I have an inline function for which I am facing compilation issues during linking (relocation error:... symbol has been discarded with discarded section ...). I made it a normal function and it worked.
Now some of my seniors told me try with static inline.
Below is my function:
inline void wizSendNotifier (const char* nn_name, bpDU* arg=0, int aspect = -1)
{
wizuiNotifier* notifier = ::wizNtrKit.getNotifier (nn_name);
notifier->notify (arg, aspect);
}
and this not inside a class. This is inside a header file!
I guess the call to a static function should be done only in the particular TU where it is defined.
Since my function is in a header file and if i make it static, will it be the case that where ever I include that header file the static function can used used in that translation unit?
The non-static inline function declaration refers to the same function in every translation unit (source file) that uses it.
The One Definition Rule requires that the body of the function definition is identical in every TU that contains it, with a longish definition of "identical". This is usually satisfied provided that the source files all use the same header, and provided that the function doesn't use any global names with internal linkage (including static functions) or any macros that are defined differently in different TUs.
I don't remember encountering that particular linker error before, but it's at least possible that one of these restrictions is responsible. It's your responsibility to satisfy the requirements: undefined behavior with no diagnostic required if you don't.
The static inline function declaration refers to a different function in each translation unit, that just so happens to have the same name. It can use static global names or macros that are different in different TUs, in which case the function might behave differently in the different TUs, even though its definition in the header file "looks the same".
Because of this difference, if the function contains any static local variables then it behaves differently according to whether it is static or not. If it is static then each TU has its own version of the function and hence its own copy of the static local variables. If it's inline only, then there is only one copy of the static local variables used by all TUs.

extern pointer problem in c++

I have a header file that has a number of declarations like this:
extern ID3D10Device* device;
I can't make these static because of a problem with multiple translation units, and I can't have them as normal pointers for a similar reason. However when I try to build the program I get unresolved external symbol linker errors. I'm assuming that this is because I'm attempting to use the pointers without defining them first. This is the problem however, as the way you initialise these DirectX objects is by passing the address of the pointers as parameters into specialist methods. - I may be wrong but I am assuming this is the problem as the compiler / linker / whatever can't see the definitions.
All I'm trying to do is have these pointers (for the graphics device, depth buffer etc) visible to multiple classes. How can this be achieved?
You need the pointers to be defined in some translation unit. The linker is complaining because it seems you haven't done that anywhere. You should declare them at file scope as
ID3D10Device* device = NULL;
in the source file where you call the DirectX function that initializes them. Just make sure the declaration is only made in one source file, then the extern statement should be placed in the associated header file which is included by all translation units that need to use these pointers.
When you externally define a variable like this, the compiler is not reserving any memory for that variable until it sees a definition inside a code module itself. So if you are going to be passing these pointers by-reference to a function for initializing their values, they must be defined in a code module somewhere.
You only need to define them in a single code module ... then place the extern declarations inside a header file you include in the rest of your code modules that require access to the pointer variables. That shouldn't create any linker errors due to duplicate definitions.
I can't make these static because of a problem with multiple translation units
If you need a different variable in different TU (translation units), make it static: this way the variable will be specific to each TU.
A declaration of a variable is also definition unless the extern is used.
You must have one (and only one) definition of a variable in the program.
To have a global variable:
Declare it with the extern keyword in some header file.
Include this header in every TU that needs to use the variable. Never declare the variable directly, never bypass the header inclusion.
Define the variable: a declaration without the extern keyword will define the variable in one TU. You need to include the header file in the same TU to guaranty consistency between the extern declaration and the definition.
the way you initialise these DirectX objects is by passing the address
of the pointers as parameters into specialist methods
To solve this part of the problem, you could do something like this (in a .cpp file):
ID3D10Device* device;
struct Foo {
Foo(ID3D10Device **pdevice) { specialist_method(pdevice); }
};
Foo f(&device);
Beware of the "static initialization order fiasco", though -- it's safe to use device from main, or code called from main, because it will definitely be initialized before that code executes. It's not necessarily safe to use it from other initializers executed before main, because the order of initialization of statics in different translation units is unspecified (within a TU, they're initialized in order of either declaration or definition, I forget which). So device might still be a null pointer in that code. Likewise, specialist_method can't necessarily rely on other statics having been initialized.
There are extra tricks you can use if you need to enforce initialization orders, I'd guess that all the common ones are on SO already in other questions.