[C++]function template with static keyword - c++

code from google's v8 js engine, allocation.h:
template <typename T>
static void DeleteArray(T* array) {
delete[] array;
}
This is a function template (top level, not in any class).
But what the static keyword is for?

That it's a template is actually a side-issue.
It being static means the function is not visible outside of the file (but since it's in a header and headers are effectively part of the files that include them, that means outside of the file that includes the header; and each file that includes the header effectively has its own, identical but private version of the function).
From http://msdn.microsoft.com/en-us/library/s1sb61xd%28VS.80%29.aspx:
"When modifying a variable or function
at file scope, the static keyword
specifies that the variable or
function has internal linkage (its
name is not visible from outside the
file in which it is declared)."
See here fore more on what it means to have this in a header file:
C/C++: Static function in header file, what does it mean?

The static keyword gives the definition "internal linkage", which means it would be legal to give the name DeleteArray another meaning or a different definition in a different source file. (Just as is the case with static void f(); or static int i;.) But I can't imagine anyone would want to do that.
Use of static this way in C++ is deprecated. This declaration would probably be better without the static keyword, making it implicitly extern (and still inline). In that case, the linker would be allowed to combine any definitions of DeleteArray<T>(T*) for the same T from multiple objects, since they would be the same thing.

static functions (outside of a class) cannot be used outside the defining file. It's a holdover from C where there are no namespaces. I bet you'll find that DeleteArray() isn't called from another file, unless it's been redefined in that other file.

Related

C++17: Defining static constexpr member functons in .cpp file

I have a static constexpr member function that i declare in the .h file. If i define the function right away in the header file, everything works perfectly. I have the general inclination to define functions in the .cpp file (even if i want them inlined, i would use the inline keyword and again do so) so i when i try to do it, it seems okay at first but when i try to call this function i get the following error:
static constexpr uint16_t ClassA::myFoo()' used before its definition
I would like learn if there is a way to define a static constexpr member function in the .cpp file rather than the header. If thats not possible or maybe limited due the compiler i am using, is there any side effects defining the function in the .h file ? (I know it is explicitly inline for normal functions but i am not sure for a constexper static function).
PS: I am using arm-none-eabi-g++ (c++17) and Clion for a small embedded project.
I would like learn if there is a way to define a static constexpr member function in the .cpp file rather than the header.
Yes... but you must define the function in every TU where it is used because it is an inline function. As such, it is simpler to put the definition into a header so that same definition will be included into all the TUs that need it.
It is an inline function because constexpr functions are implicitly inline functions - i.e. whether or not you use the inline keyword.
is there any side effects defining the function in the .h file ?
The effect of doing this is that the function definition will be included into every TU that include the header. I don't quite understand what you mean by "side" effect in this context.

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.

Accessing a function through inclusion vs declaring static

I have a header file I want to include in another cpp file. I want to know what is the difference if I write the header file like this,
#include <iostream>
#include <string>
using namespace std;
string ret()
{
return "called";
}
===================================
#include <iostream>
#include <string>
using namespace std;
static string ret()
{
return "called";
}
I can access the ret() function anyway!! So, what's the use of the static?
That is a pretty evil header file you're showing.
Never put using namespace std; into a header file. This forces anyone including the header to have all of std in the global namespace.
Use some form of include guards.
static makes the function invisible outside the .cpp where it's included. This means that every .cpp which includes the header will have its own copy of the function. static (non-member) functions should only be used if you specifically need this behaviour.
If you don't use static, you should either move the definition from the header into a source file (if you want it defined once), or declare the function inline (its code will then be inlined on every call site, if possible). If you do neither of these, you'll get multiple definition errors if you include the header in more than one source file.
The first header file defines a function called ret with external linkage in every translation unit that includes it. This is incorrect if more than one such TU is linked in the same program.
The second header file defines a function called ret with internal linkage in every translation unit that includes it. This means that each TU has its own private copy of the function (with a different address) no matter how many are linked together.
There are three correct ways to share code using a header file:
function with internal linkage (as in your second header, or in C++11 by putting it in a nameless namespace).
inline function with external linkage (replace static with inline). The meaning of inline is that although there is only one copy of the function in the program, every TU that uses the function contains its definition.
declare the function in the header, and define in it exactly one .cpp file (for example ret.cpp).
In C++03 there was a fourth way:
function with external linkage in a nameless namespace
I believe this is still available in C++11, but in C++11 functions in nameless namespaces have internal linkage by default. I'm not aware of any use in C++11 for making a function in a nameless namespace have external linkage. So as far as functions are concerned, nameless namespaces are a nice way of giving the function internal linkage.
Which one you use depends on your needs. The third option means that you can change the definition of the function without re-compiling the calling code, although you'd still need to re-link the executable unless the function is in a dll.
The first two (static or inline) differ in their behaviour if:
the function contains static local variables,
you compare function pointers to ret taken in different TUs,
you examine your executable size or symbol table,
the definition of the function is different in different TUs (perhaps due to different #defines), which is forbidden if the function has external linkage but not if internal.
Otherwise they're much the same.
According to the standard, inline is also a hint that the compiler should optimize calls to that function for fast execution (which in practice means, inline the code at the call site). Most compilers ignore this hint most of the time. They will happily inline a static but non-inline function if they assess it to be a good candidate for inlining, and they will happily avoid inlining an inline function if they assess it to be a bad candidate for inlining.
Use header guards.
Don't use "using namespace" in header files. (Actually, don't use "using" in header files. Use identifiers fully qualified.)
And use a header for declaring functions, not for defining them. You will want the code for ret() to be present in the resulting executable only once. You achieve this by putting the definition (code) of ret() in a .cpp file. One .cpp file, not multiple ones (by including the definition).
The header file lists the declaration of the function ret() so that other code "knows" that the function exists, which parameter it takes, and what it returns.
If you define c++ methods as static in the header file, each translation unit ( each .cpp file which includes that header file ) will have different versions of those static methods - they will not have the same address space.
Hence the size of your program will increase unnecessarily.
Also, just for clarity:
Defining a method as static only in the .cpp file means that the method has static linkage and is only accessible from other methods within the same .cpp file.

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.

why do " int ClassName :: VariableName " always needed to complete linkage?

class X {
static int i;
// some other function, variable declaration, cons, dest
};
int X :: i ; **(!)**
Why must I write that (!) line, always ?
If I dont write, compiler cannot complete internal linkage, and so it gives ( I assume ) linker error. Why ?
This is known as the One Definition Rule. Each global object (technically, each object with external linkage) must be defined in exactly one source file (technically, in one translation unit). However, it can be declared as many times as you like.
Typically, a class definition will be in a header file, which might be included by many source files. So any static members can't be defined there, only declared, otherwise there will be multiple definitions. You must separately define the static members in exactly one source file, in order for the linker to find exactly one definition. That is what the line marked (!) does.
Because that is how static members work. They exist apart from the instances directly in the class.
You can't define them inside the class, because then you would have multiple definitions for every implementation file that is using your class.
Therefore you need to choose one implementation file that will actually define the static member.
The static variable must be defined (as opposed to declared) in a TU (i.e. a cpp file).
If it's only declared and not defined, no storage is allocated for it, so the linker can't find it.
static int i; is a declaration, i.e. tells to the compiler that in some translation unit (=>.cpp file) such static field will be actually defined. It is needed to let the compiler know that such variable exists and to let you use it in each translation unit where it's declared.
int X :: i;, instead, is a definition, it tells to the compiler to actually provide the space for that variable. It must stay in a single .cpp, otherwise each translation unit would provide some space for it on its own (and the linker would complain).
It's the exact same reason why for globals you need an extern declaration in every file that needs to use it (usually put in a header) and a normal definition in the single .cpp that defines it.
C++ makes a clear distinction between declaration and definition. You need to tell the compiler two things:
The data type of the variable: declaration.
The place in memory on where you want your variable to be located: definition.
This is usually done in one single step, ie a local int variable:
void f() {
int x; // Declaration and definition.
}
Since a .hpp header file can be included on many .cpp files, your (!) line must reside on a single specific .cpp, usually outside any header file.
Static class members are shared among all class instances (there is one and only place in memory where such variable resides) and therefore static int i; inside class declaration represents variable declaration only - and you need to allocate memory for that variable somewhere - you need to define it - which is done in implementation file with int X::i;
The class definition only defines the member, but it must exist in a single compilation unit (i.e. a .cpp file).
You could say it is part of the "one-definition rule".