When should I consider using static functions defined at file scope?
I typically use them when the task done in one such function doesn't really belong in member functions of any class and when such a task is only needed (repeatedly) in a certain source file.
Is my usage in line with why this feature exists? Or am I hijacking a concept that's intended for something else?
That's a perfectly valid use of file-scope static functions, but keep in mind that this usage of static has been deprecated for quite some time. It's generally preferred to use anonymous namespaces instead.
I do a similar thing when it make sense to have functions and/of data that are not part of the class interface but rather an implementation detail.
But I don't use the keyword static. Instead, I put the functions and/or data in an unnamed namespace.
First off, the term you are looking for is internal linkage. Your question really should be: "Which entities should have internal linkage?" The static keyword, or alternatively unnamed namespaces, are just implementation mechanisms to achieve internal linkage.
Now the answer should be obvious: All entities that are only required inside one single translation unit may be given internal linkage, and there are benefits in doing so: One is that the compiler can make use of the information that an entity cannot ever be seen by any other translation unit, so it can for example avoid emitting code that might be required otherwise, or inline more aggressively. Another reason is that you minimize the risk of accidental ODR violations if you happen to pick a name that is also used locally in some other TU.
A typical example is like this:
my_lib.hpp:
#ifndef H_MY_LIB
#define H_MY_LIB
namespace foo
{
void do_an_awesome_thing(void * p, std::size_t n);
}
#endif
my_lib.cpp:
#include "my_lib.hpp"
namespace foo
{
namespace
{
void helper(void * p) { /* ... */ }
bool aux(std::size_t n, float f) { /* ... */ }
constexpr char usage[] = R"(This is how you do it...)";
constexpr float some_factor = 1.25;
}
void do_an_awesome_thing(void *p, std::size_t n)
{
if (!aux(n, some_factor)) { LOG_AND_DIE(usage); }
helper(p);
}
}
Now your can be sure that your translation unit does not impose any undue link-time burden on the remainder of your program.
The placement of the unnamed namespace is a matter of taste; you can either have it inside your usual namespace, or at the top level. The effect is the same.
Related
I have a non-template struct in a header file:
struct X {
constexpr X() : /* ... */ { /* ... */ }
constexpr void f() {
// ...
}
};
With functions of varying size. This is used in a lot of different translation units, and each function appears in multiple object files for them to be discarded in the final executable.
What I want is for the definitions to be in a single object file, and the other translation units can either inline the function or use an external definition (something like the extern inline semantics from C). How can I do that?
It seems to work with templates and extern template:
namespace detail {
template<std::nullptr_t>
struct X_base {
constexpr X_base() // ...
constexpr void f() // ...
};
extern template struct X_base<nullptr>;
}
struct X : detail::X_base<nullptr> {
using X_base::X_base;
};
// X.cpp
#include <X.hpp>
template struct detail::X_base<nullptr>;
But are there any major downsides to this (longer symbol names, confusing to read, needs documentation, etc.), or are there any easier ways to do this?
C++ doesn’t have the notion of an inline function that must be emitted in one translation unit and which therefore certainly need not be emitted anywhere else. (It doesn’t have the notion of emitting object code at all, but the point is that there’s no syntax that says “I promise this definition is ODR-identical to the others except that it and only it bears this marker.” so that compilers could do that.)
However, the behavior you want is the obvious way of implementing C++20 modules: because the definition of an inline function in a module is known to be the only definition, it can and should be emitted once in case several importing translation units need an out-of-line copy of it. (Inlining is still possible because the definition is made available in a compiler-internal form as part of building the module.) Bear in mind that member functions defined in a class in a module are not automatically inline, although constexpr still implies it.
Another ugly workaround is to make non-inline wrappers to be used outside of constant evaluation, although this could get unwieldy if there were multiple levels of constexpr functions that might also be used at runtime.
There are two implications of using the inline keyword(§ 7.1.3/4):
It hints the compiler that substitution of function body at the point of call is preferable over the usual function call mechanism.
Even if the inline substitution is omitted, the other rules(especially w.r.t One Definition Rule) for inline are followed.
Usually any mainstream compiler will substitute function body at the point of call if needed, so marking function inline merely for #1 is not really needed.
Further w.r.t #2, As I understand when you declare a function as static inline function,
The static keyword on the function forces the inline function to have an internal linkage(inline functions have external linkage) Each instance of such a function is treated as a separate function(address of each function is different) and each instance of these functions have their own copies of static local variables & string literals(an inline function has only one copy of these)
Thus such a function acts like any other static function and the keyword inline has no importance anymore, it becomes redundant.
So, Practically marking a function static and inline both has no use at all. Either it should be static(not most preferred) or inline(most preferred),
So, Is using static and inline together on a function practically useless?
Your analysis is correct, but doesn't necessarily imply uselessness. Even if most compilers do automatically inline functions (reason #1), it's best to declare inline just to describe intent.
Disregarding interaction with inline, static functions should be used sparingly. The static modifier at namespace scope was formerly deprecated in favor of unnamed namespaces (C++03 §D.2). For some obscure reason that I can't recall it was removed from deprecation in C++11 but you should seldom need it.
So, Practically marking a function static and inline both has no use at all. Either it should be static(not most preferred) or inline(most preferred),
There's no notion of preference. static implies that different functions with the same signature may exist in different .cpp files (translation units). inline without static means that it's OK for different translation units to define the same function with identical definitions.
What is preferred is to use an unnamed namespace instead of static:
namespace {
inline void better(); // give the function a unique name
}
static inline void worse(); // kludge the linker to allowing duplicates
Static and inline are orthogonal (independent). Static means the function should not be visible outside of the translation unit, inline is a hint to the compiler the programmer would like to have this function inlined. Those two are not related.
Using static inline makes sense when the inlined function is not used outside of the translation unit. By using it you can prevent a situation of accidental violation of ODR rule by naming another inlined function in another tranlation unit with the same name.
Example:
source1.cpp:
inline int Foo()
{
return 1;
}
int Bar1()
{
return Foo();
}
source2.cpp:
inline int Foo()
{
return 2;
}
int Bar2()
{
return Foo();
}
Without using static on Foo (or without using an anonymous namespace, which is preferred way by most C++ programmers), this example violates ODR and the results are undefined. You can test with Visual Studio the result of Bar1/Bar2 will depend on compiler settings - in Debug configuration both Bar1 and Bar2 will return the same value (inlining not used, one implementation selected randomly by the linker), in Release configuration each of them will return the intended value.
I may not be completely right about this, but as far as I know declaring a function static inline is the only way to make (or allow) the compiler to generate a machine code where the function really is not defined in the compiled code at all, and all you have is a direct substitution of the function call into a sequence of instructions, like it were just a regular procedure body, with no trace in the machine code of a procedure call relative to that function definition from the source code.
That is, only with static inline you can really substitute the use of a macro, inline by itself is not enough.
A simple Google search for "static inline" will show you compiler documentation pages that talk about it. I guess this should be enough to answer your question, and say, "no, it is not practically useless". Here is one example of a site discussing the use of inline, and specifically of static inline http://www.greenend.org.uk/rjk/tech/inline.html
If you talk about free functions (namespace scope), then your assumption is correct. static inline functions indeed don't have much value. So static inline is simply a static function, which automatically satisfies ODR and inline is redundant for ODR purpose.
However when we talk about member methods (class scope), the static inline function does have the value.
Once you declare a class method as inline, it's full body has to be visible to all translation units which includes that class.
Remember that static keyword has a different meaning when it comes for a class.
Edit: As you may know that static function inside a class doesn't have internal linkage, in other words a class cannot have different copies of its static method depending on the translation (.cpp) units.
But a free static function at namespace/global scope does have different copies per every translation unit.
e.g.
// file.h
static void foo () {}
struct A {
static void foo () {}
};
// file1.cpp
#include"file.h"
void x1 ()
{
foo(); // different function exclusive to file1.cpp
A::foo(); // same function
}
// file2.cpp
#include"file.h"
void x2 ()
{
foo(); // different function exclusive to file2.cpp
A::foo(); // same function
}
I just read a man page for gcc and it specifically states the use of static inline with a compiler flag. In the case of the flag, it inlines the function and if it is also static and is inlined in every instance that it is called, then it gets rid of the function definition which will never be used in the created object file, thereby reducing the size of the generated code by that little bit.
I've been learning C++, and I've come across static variable (I have prior knowledge from C89), and in the resource i'm using, they've declared a static variable in a class such as:
class nameHere
{
public:
static int totalNum;
}
int nameHere::totalNum = 0;
int main()
{}
For Example.
What I don't understand is that, since I've already declared that the static variable is an integer in the class definition, why do I need to also declare it as an integer outside of the class definition?
Would it not make sense to simply initialise it like so:
nameHere::totalNum = 0;
int main()
{}
Is there a particular reason or simply a convention of C++?
Thanks for all the help!
This would (probably) make the language even more difficult to parse (and it's already almost insanely difficult to parse anyway).
As it is, the datatype (int, long, my_class, whatever) tells the compiler that what it's seeing is the beginning of a declaration (which, in this case, is also a definition). Without that, the compiler would have a rather more difficult time sorting things out.
In the specific case of things at global scope, it wouldn't be that bad, because at global scope about all you can have is a series of declarations. At any other scope, however, things would be more difficult (and having one rule at global scope, and another elsewhere would be ugly indeed).
In C++11 you can simply initialize the variable inside the class:
class nameHere
{
public:
static const int totalNum = {0};
}
There is a difference between a definition and a declaration.
While the static variable in the class has been declared, it has not been defined. The One Definition Rule, explains declarations and definitions and states
In any translation unit, a template, type, function, or object can have no more than one definition. Some of these can have any number of declarations.
Therefore, the full type of the object must be used when declaring the variable.
Even though there are no static classes in C++, coming from a Java background I use to create a helper class like Util containing only static methods. Is this considered bad style or usual practice? One alternative I see is to use C functions (no class context at all). What other alternatives are there? What are there advantages and disadvantages and under which circumstances would I use any of these.
defining bunch of static methods in c++ suggests namespacing static functions as one alternative, though I fail to see what effects the static keyword without class context has.
If you want to create a collection of utility functions without clobbering the global namespace, you should just create regular functions in their own namespace:
namespace utility {
int helper1();
void helper2();
};
You probably don't want to make them static functions either.
Within the context of a non-member function (as opposed to a member function), the static keyword in C and C++ simply limits the scope of the function to the current source file (that is, it sort of makes the function private to the current file). It's usually only used to implement internal helper functions used by library code written in C, so that the resulting helper functions don't have symbols that are exposed to other programs. This is important for preventing clashes between names, since C doesn't have namespaces.
In C++, classes with only static methods is mostly used in template metaprogramming.
For example, I want to calculate fibonacci numbers at compile-time itself, and at runtime I want them to print only, then I can write this program:
#include <iostream>
template<int N>
struct Fibonacci
{
static const int value = Fibonacci<N-1>::value + Fibonacci<N-2>::value;
static void print()
{
Fibonacci<N-1>::print();
std::cout << value << std::endl;
}
};
template<>
struct Fibonacci<0>
{
static const int value = 0;
static void print()
{
std::cout << value << std::endl;
}
};
template<>
struct Fibonacci<1>
{
static const int value = 1;
static void print()
{
Fibonacci<0>::print();
std::cout << value << std::endl;
}
};
int main() {
Fibonacci<20>::print(); //print first 20 finonacci numbers
return 0;
}
Online demo : http://www.ideone.com/oH79u
C++ is a multi paradigm language, so if you need some util functions that perhaps don't really fit in a class at all, then I would just make them free functions. I don't see a reason to put them into a class, just for OOP's sake.
There is no advantage that I can see to making all functions static and putting them in a class, over having them just as free functions. Personally, I think free functions are then an easier to work with option.
As many others have pointed out, free functions inside a namespace is an approach that's often taken for this sort of thing in c++.
One case I'd make for classes with all static functions is when you'd like to expose a set of functions to information derived from template parameters, i.e.
template <typename Ty>
class utils
{
public :
// if you need to setup a bunch of secondary types, based on "Ty" that will be used
// by your utility functions
struct item_type
{
Ty data;
// etc
};
// a set of utilities
static void foo(Ty &data1, item_type &item)
{
// etc
}
};
You can use this to achieve the effect of a template'd namespace:
int main ()
{
double data;
utils<double>::item_type item ;
utils<double>::foo(data, item);
return 0;
}
If you're not using templates just stick with namespaces.
Hope this helps.
There is no real issue with declaring static methods within a class. Although namespaces are more suitable for this purpose for the reasons mentioned in the post you are referring to.
Using C functions can generate name collisions, unless you decide on a naming convention, prefixing your functions with stuff, for example btFunctionA, btFunctionB etc.
You will want to keep your symbols within namespaces to avoid that, you are using C++ and not C after all.
Static functions within a namespace aren't any different from non-static. I believe the static keyword is simply ignored in this context.
In C++, just make them free functions. There's no need or reason to place them in a class at all. Unless you're doing shizzle with templates.
This may be relevant to your interests. It is an article that, uh, examines the different approaches to classes and functions in Java compared to other languages.
http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html
There is one other situation in which a static class might be preferred to a namespace: when you want to make the data private so that it can't be directly modified from outside the class/namespace, but for performance reasons you want to have have public inline functions that operate on it. I don't think there is any way to do that with a namespace, other than by declaring a class inside the namespace.
What does it exactly mean when the Standard states
$7.3.1.1/2 - "The use of the static
keyword is deprecated when declaring
variables in a namespace scope (see
annex D); the unnamed-namespace
provides a superior alternative."
I have referred this but it does not cover what I am looking for.
Is there an example where the superiority is clearly demonstrated.
NB: I know about how unnamed namespaces can make extern variables visible in the translation unit and yet hide them from other translation units. But the point of this post is about 'static namespace scope' names (e.g global static variables)
What does it exactly mean?
Technically deprecated means that a future standard may remove the feature.
In practice that isn't going to happen, because of the need to support old code.
So in practice it means, "strongly discouraged".
Example of superiority of unnamed namespace
An unnamed namespace is generally superior because what you have in that namespace can have external linkage.
In C++98 external linkage is necessary for things that can be template parameters, e.g., if you want to templatize on a char const*, it must be pointer to char that has external linkage.
#include <iostream>
// Compile with "-D LINKAGE=static" to see problem with "static"
#ifndef LINKAGE
# define LINKAGE extern
#endif
template< char const* s >
void foo()
{
std::cout << s << std::endl;
}
namespace {
LINKAGE char const message[] = "Hello, world!";
} // namespace anon
int main()
{
foo<message>();
}
That said, it's a bit inconsistent that static isn't also deprecated for functions.
This:
static int func_for_this_file_only() { ... }
is "as good as" this:
namespace { int func_for_this_file_only() { ... } }
but static can't be used for this:
namespace { class class_for_this_file_only { ... } }
Therefore, anonymous namespaces in C++ are more versatile and superior to static.
(I'm sure someone will argue with that conclusion, but as a C hacker I think the anonymous namespace solution is better.)
Interestingly, ISO/IEC 14882:2011 (C++11) removed this language (in fact, it removes the whole paragraph §7.3.1.1/2). It also removes the mention of static from Annex D.
Thus, using the storage class specifier static to give a name internal linkage still works (§3.5/3) and is no longer deprecated.
The goal is to define a symbol that exists only within your own translation unit. This can be "translation unit global" and may be a variable or a function.
This is commonly used in a class definition file as an alternative to private static class members as the static members have to be declared in the header, but a free-function does not have to be (unless it has to be a friend, which it virtual never actually needs to be, by the way).
The use of static would be:
static size_t BUFSIZE = 2048; // assume not const for this example
static int myCallback( void * ptr );
The use of an anonymous namespace is
namespace {
size_t BUFSIZE = 2048;
int myCallback( void * ptr );
}
The standard is saying that the second construct is preferred. We have found that sometimes it is advantageous still to use static in addition to the anonymous namespace to actually reduce the binary size.