Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are static data members safe as C++ default arguments?

Do I need to worry about the static initialization order fiasco when using a static data member as a default argument value? For example:

class Thing {

    static double const default_blarg;  // initialized in another file

    void run(double blarg=default_blarg);

};

I know default_blarg will be initialized at a mostly-unspecified point at link time, but I'm not sure when the default argument to run is initialized. If it's at some point that could be before default_blarg is initialized, what approach could I use to safely expose the default value as part of the class interface without repeating it? Would using constexpr for the static data member make it safe?

Note that I'm aware that this could yield some very confusing behavior if default_blarg wasn't const (that's why it is), and I'm not trying to use a non-static data member.

like image 514
jbosch Avatar asked Sep 08 '16 17:09

jbosch


People also ask

Can C have default arguments?

Generally no, but in gcc You may make the last parameter of funcA() optional with a macro.

Where should you initialize a static data member?

The initializer for a static data member is in the scope of the class declaring the member. A static data member can be of any type except for void or void qualified with const or volatile . You cannot declare a static data member as mutable . You can only have one definition of a static member in a program.

Is a static data member it can only be initialized at its definition?

8.1: Static data. Any data member of a class can be declared static ; be it in the public or private section of the class interface. Such a data member is created and initialized only once, in contrast to non-static data members which are created again and again for each object of the class.

What are static data members in C++?

Static data members in C++. Static data member are class members that are declared using static keyword A static member has certain special characteristics These are: Only one copy of that member is created for the entire class and is shared by all the objects of that class , no matter how many objects are created.

How is the value of a static variable stored in C++?

The value of a static member variable of a C++ class is stored only once for the entire run of the C++ program. No matter how many instances of this class you make, that value will be the same. That static variable is a global variable, when it comes to how its value is stored.

How many copies of the static data member are there?

There is only one copy of the static data member in the class, even if there are many class objects. This is because all the objects share the static data member. The static data member is always initialized to zero when the first class object is created.

Why static variables should not be declared inside structure?

6) Static variables should not be declared inside structure. The reason is C compiler requires the entire structure elements to be placed together (i.e.) memory allocation for structure members should be contiguous.


2 Answers

You still have to be worried about the static initialization order fiasco. Lets say you have a.cpp and b.cpp. In a.cpp you have

double const Thing::default_blarg = 0;

Now in a.cpp any call to run after this point will have a initialized default and you are good to go. Unfortunately in b.cpp you have another static object that happens to create an instance of Thing and call run.

Now we do not know what will happen. If b.cpp runs first then default_blarg is not initialized and we have undefined behavior.

Now for you second part

but I'm not sure when the default argument to run is initialized

The default arguments of a function are evaluated each time the function is called. So as long as the function is called after default_blarg is initialized(and as noted above it may not) you will be okay.

like image 125
NathanOliver Avatar answered Nov 07 '22 03:11

NathanOliver


From the C++11 Standard, Section 8.3.6/9:

Default arguments are evaluated each time the function is called.

As long as Thing::default_blarg is initialized before Thing::run is called, you should see predictable behavior.

like image 22
R Sahu Avatar answered Nov 07 '22 03:11

R Sahu