The static keyword and its various uses in C

0 votes
The term static has numerous meanings in C++ that I find extremely confounding, and I can never wrap my head around how it is intended to operate.

According to my understanding, static storage duration implies that it lasts throughout the lifetime of the programme in the case of a global, but in the case of a local, it means that it is zero initialised by default.

For class data members using the keyword static, the C++ Standard states:

3.7.1 Duration of static storage [basic.stc] .static]

3 The term static can be used to declare a local variable with a fixed period of storage.

4 In a class declaration, the term static added to a class data member offers the data member static storage duration.

What exactly is a local variable?

Is that a local variable of a function?

Because when you specify a function local as static, it is only initialised once, when it first enters this function.

It also just mentions storage lifetime in relation to class members; what about non-instance specificity, which is also a characteristic of static no?

Is that the period of storage?

What about the static and file scope cases?

Is it assumed that all global variables have a static storage lifespan by default?

The following (from section 3.7.1) appears to support this:

1 All variables that do not have dynamic storage duration, thread storage duration, or local storage duration have static storage duration.

These entities will be stored for the length of the programme (3.6.2, 3.6.3)

What is the relationship between static and variable linkage?

Can someone please explain the multiple usage for the static keyword in English and also teach me when to initialise a static class member?
Jun 27, 2022 in C++ by Nicholas
• 7,760 points
525 views

1 answer to this question.

0 votes

Static variables exist during the "lifetime" of the translation unit in which they are declared, and:

It cannot be accessible from any other translation unit if it is in a namespace scope (i.e. outside of functions and classes). 

This is referred to as "internal linking" or "static storage lifetime." 

(Except for constexpr, do not do this in headers; otherwise, you would wind up with a different variable in each translation unit, which is really confusing.)

If it is a variable in a function, it, like any other local variable, cannot be accessed from outside the function. 

(This is the mentioned local)

Class members have no limited scope owing to static, but they may be referenced from both the class and an instance (like std::string::npos).

locations as code:

static std::string namespaceScope = "Hello";
void foo() {
    static std::string functionScope= "World";
}
struct A {
   static std::string classScope = "!";
};

Before any function in a translation unit is executed (possibly after main started execution), variables with static storage duration (namespace scope) in that translation unit are "constant initialised" (to constexpr where possible, or zero otherwise), and non-locals are "dynamically initialised" properly in the order they are defined in the translation unit (for things like std::string="HI"; that aren't constexpr). 

Finally, when execution "reaches" the line where function-local statics are defined, they are initialised. 

In the reverse sequence of initialization, all static variables are deleted.

The simplest approach to do this right is to convert any static variables that are not constexpr initialised into function static locals, which ensures that all of your statics/globals are properly initialised when you try to use them regardless of what, avoiding the static initialization order issue.

T& get_global() {
    static T global = initial_value();
    return global;
}

Be cautious, because while the standard specifies namespace-scope variables have "static storage duration" by default, they mean the "lifetime of the translation unit" bit, which does not exclude access outside of the file.

Functions

Significantly simpler, static is frequently used as a class member function and is only very seldom used for a free-standing function.

A static member function varies from a standard member function in that it may be called without an instance of a class, and since it lacks an instance, it cannot access the class's non-static members. 

Static variables are useful when you need a function for a class that does not refer to any instance members, or for handling static member variables.

struct A {
    A() {++A_count;}
    A(const A&) {++A_count;}
    A(A&&) {++A_count;}
    ~A() {--A_count;}

    static int get_count() {return A_count;}
private:
    static int A_count;
}

int main() {
    A var;

    int c0 = var.get_count(); //some compilers give a warning, but it's ok.
    int c1 = A::get_count(); //normal way
}

A static free-function indicates that the function will not be referenced to by any other translation unit, allowing the linker to completely disregard it. 

This serves only a few purposes:

Can be used in a cpp file to ensure that the function is never called from anywhere else.

If you place it in a header, each file will have its own copy of the function. 

It's pointless since inline achieves the same thing.

Reduces labour to shorten connection time.

Each translation unit can have a function with the same name that does something different. 

For example, you might include a static void log(const char*) in each cpp file, and they would all log in a different way

answered Jun 27, 2022 by Damon
• 4,960 points

Related Questions In C++

0 votes
0 answers

Difference between for loop and the range based loop in C++

The distinction between a for loop and ...READ MORE

Jul 11, 2022 in C++ by Nicholas
• 7,760 points
593 views
0 votes
1 answer

What is the difference between operator overloading and operator overriding in C++?

Some people use the latter word to ...READ MORE

answered Aug 2, 2022 in C++ by Damon
• 4,960 points
1,929 views
0 votes
0 answers

What is the difference between std::list<std::pair> and std::map in C++ STL?

What distinguishes std::list<std::pair> from std::map? Does the ...READ MORE

Aug 17, 2022 in C++ by Nicholas
• 7,760 points
620 views
0 votes
0 answers

What are the differences between struct and class in C++?

I now want to understand the distinctions ...READ MORE

Aug 17, 2022 in C++ by Nicholas
• 7,760 points
508 views
0 votes
0 answers

How to access static members of a class?

I'm learning C++ and Qt, but even the simplest code that I copy and paste from a book produces problems. On Ubuntu 10.04, I'm using g++4.4.2 with the QtCreator IDE.  Is there a distinction between the syntax of the g++ compiler and those of other compilers?  When I try to access static members, for example, something always goes wrong. #include <iostream> using namespace std; class A { ...READ MORE

Jul 7, 2022 in C++ by Nicholas
• 7,760 points
471 views
0 votes
1 answer

what do you mean by static block in java?

Static block is used for initializing the ...READ MORE

answered Jun 18, 2018 in Java by scarlett
• 1,290 points
895 views
0 votes
1 answer

Interface variable are static and final by default. Why?

Interface variables are static because Java interfaces ...READ MORE

answered Jul 4, 2018 in Java by Daisy
• 8,140 points
13,462 views
0 votes
1 answer

setuptools: build shared libary from C++ code, then build Cython wrapper linked to shared libary

There is a seemingly undocumented feature of setup that ...READ MORE

answered Sep 11, 2018 in Python by Priyaj
• 58,020 points
686 views
0 votes
1 answer

Cases of static and dynamic binding in C++

When an object's static type is used to associate it with a member function, this is known as static binding (understand the type of its class). When a pointer or reference is associated with a member function based on the dynamic type of the object, this is known as dynamic binding (understand the instance of the variable at runtime). Before continuing, keep in mind that dynamic binding only works with pointers, references, and virtual functions for the base class. Because everything needed to call the function is known at compile time, the first call is a static binding (also known as early binding). Derived1 d1(1, 10); d1.display_data(); You already know that the d1 instance is a Derived1 automatic variable, and that it will call the Derived1::display data method (). The first condition is incorrect: d1 is neither a pointer nor a reference. The second condition isn't acceptable:  There is no virtual Derived1::display data. The second call is for ...READ MORE

answered Jun 7, 2022 in C++ by Damon
• 4,960 points
689 views
0 votes
1 answer

What is the difference between public, private, and protected inheritance in C++?

To begin answering that question, let me characterise member accessors in my own terms.  If you already know this, proceed to the section "next:". I'm aware of three types of accessors: public, protected, and private. Let: class Base { public: ...READ MORE

answered Jul 11, 2022 in C++ by Damon
• 4,960 points
747 views
webinar REGISTER FOR FREE WEBINAR X
REGISTER NOW
webinar_success Thank you for registering Join Edureka Meetup community for 100+ Free Webinars each month JOIN MEETUP GROUP