What is default storage class for global variables? - c++

What is default storage class of a global variable?
While searching on web I found, some sites say it is static. But, static means internal linkage and the variable can not be available outside the file scope i.e it should not be available to other object files. But, they still can be accessed to other files using declarations like extern int i.
And, if I explicitly mention static to global variable then it is not available outside the file scope.
Then, what is correct default storage class for the global variables?

The default storage duration is static, but default linkage is external. You're not the only one to find it a bit confusing. The C Book (always a good reference) says:
"You'll probably find the interactions
between these various elements to be
both complex and confusing: that's
because they are!"
The section with that quote, Declarations, Definitions and Accessibility, has a helpful table (8.1). The last row describes the case you're interested in. As it notes, data objects with no storage class specifier have external linkage and static duration.

There's no "default storage class" for what is commonly known as "global" variables. When a variable is defined in namespace scope it always has static storage duration. There's no way to change that, which is why the idea of something "default" is not applicable here. (And storage duration is what it is correctly called.)
When you apply the keyword static to a variable defined in namespace scope it does not affect its storage duration - it was static already and it remains static - but it affects it linkage. The keyword static changes the linkage of such variable from external (default) to internal. Linkage is a separate concept, virtually unrelated to storage duration.

Related

Is there any sense to declare static global variable as inline?

Consider, global variable (not static class member!) is declared in the header file:
inline static int i{};
It is valid construction for several compilers that I tested, and experiments demonstrate that several distinct objects will be created in different translation units, although it is also declared as inline (it means that only one instance of that variable must exist in the program). So, has static keyword more priority than inline in that case?
So, has static keyword more priority than inline in that case?
Pretty much. static has an effect that interferes with inline. The C++ standard states that
... An inline function or variable with external linkage shall have
the same address in all translation units.
And the static qualifier imposes internal linkage, so the single address guarantee does not have to hold. Now, a name with internal linkage in different translation units is meant to denote different object in each TU, so getting multiple distinct i's is intended.
All in all, the static negates the inline. And there is no point to having a static inline variable over a plain static one.

why is "static" both storage class and linkage specifier?

The static keyword defines how a variable is to be stored in memory, i.e., in the data segment if initialized or in the BSS if uninitialized. But the keyword also specifies how a variable is to be linked, i.e., local scope only.
How or why are these two things related? Can the two be separated, or was this a necessary design consideration?
IOW, why is it that if I want my variable to exist for the duration of the program, it must be linked internally?
The keyword static can probably be seen as somewhat "overloaded".
The following usage-options are all viable:
Static local variables
Static global variables
Static member variables
Static global functions
Static member functions
Variables:
In terms of runtime, all types of static variables are essentially the same. They all reside in the data-section of the program, and their addresses remain constant throughout the execution of the program. So the only difference between them is during compilation, in the scope of declaration:
Static local variable: recognized by the compiler only in the scope of the function
Static global variable: recognized by the compiler only in the scope of the file
Static member variable: recognized by the compiler only in the scope of the class
Functions:
In terms of runtime, all types of functions (static and non-static) are essentially the same. They all reside in the code-section of the program, and their addresses remain constant throughout the execution of the program. So the only difference between them is during compilation, in the scope of declaration:
Static global function: recognized by the compiler only in the scope of the file
Static member function: recognized by the compiler only in the scope of the class
Re
“why is it that if I want my variable to exist for the duration of the program, it must be linked internally?”
no that is not so.
Program-global variables are supported, and that's the default for a non-const namespace level variable. It's just wise to avoid them (to the extent possible).
Re apparent conflation of concepts in the single keyword static, since C++ doesn't support dynamic libraries, local to the translation unit linkage is not meaningful for lifetime shorter than the program execution.

Static vs New/Malloc

I was wondering if people could shed some light on the uses of "static." I have never run into an issue where I have explicitly declared a variable or method as static. I understand that when declaring something as "static" it gets stuffed into the data segment of your program, similar to globals, and hence the variable is accessible for the run of your program. If this is the case, why not just make a static variable a global variable. Hell, why not just throw this variable on the heap using a new or a malloc, both methods ensure the variable will be available for you throughout the run of your program.
static has multiple meanings in C, and C++ heaps on even more.
In a file scope declaration (what I think the question is about), static controls the visibility of an identifier.
Let's set aside C++ and use the C concepts.
File scope identifiers which name objects or functions have linkage. Linkage can be external (program-wide) or internal (within one translation unit).
static specifies internal linkage.
This is important because if a name with internal linkage appears in multiple units, those occurrences are not related. One module can have a static foo function and another one in the same program can have a different foo function. They both exist and are reachable by the name foo from their respective units.
This is not possible with external linkage: there must be one foo.
malloc creates an object which is potentially available everywhere in a program, as long as it is not freed, but in a different sense. The object is available if you have its pointer. A pointer is a kind of "run time name": an access key to get to the object. Linkage makes an object or function available if you know its name (at compile time) and if that object and function has the right kind of linkage relative to where you're trying to access it from.
In a dynamic operating system in which multiple programs come into life and terminate, the storage for its static data and functions (whether they have external or internal linkage) is in fact dynamically allocated. The system routine which loads a program has to do something similar to malloc to fetch memory for all of the fixed areas of the program.
Sometimes C programs use malloc even for "singleton" objects that are referenced globally via global pointers. These objects behave like de-facto static variables since they basically have a lifetime which is almost that of the entire program, and are accessed through the pointer, which is accessed by name. This is useful if the objects have properties (such as size) that is not known until run time, or if their initialization is expensive and they are not always needed (only when certain cases occur in the program).
Supplemental factoids about static and extern:
In C, at file scope, extern ensures that the declaration of an object, where an initializer is omitted, is in fact a declaration. Without extern it is a tentative definition, but if an initializer is present, then it is a definition.
In C, at file scope extern doesn't mean "this declaration has external linkage", surprisingly. An extern declaration inherits linkage from a previous declaration of the same name.
A block-scope extern in C means "this name, which is being introduced into this scope, refers to the external definition with external linkage". The linkage is inherited from a previous file-scope declaration of the name, if it exists, otherwise it is external.
A block-scope static on an object controls not linkage, but storage duration. A static object is not instantiated each time on entry into the block; a single copy of it exists, and can be initialized prior to program startup. (In C++, non-constant expressions can initialize such object or its members; in that case, initialization occurs on the first execution of the block).
A block-scope static function declaration declares a function with internal linkage.
There is no way, in a block scope, to declare an external object name which has internal linkage. Paradoxically, the first extern declaration in the following snippet is correct, but the second, block-scope one, is erroneous!
static int name; /* external name with internal linkage */
extern int name; /* redundant redeclaration of the above */
void foo(void)
{
int name; /* local variable shadowing external one */
{
/* attempt to "punch through" shadow and reach external: */
extern int name; /* ERROR! */
}
}
Clearly, the word "external" has an ambiguous meaning between "outside of any function" and "program-wide linkage" and this ambiguity is embroiled in the extern keyword.
In C++, static takes on additional meanings. In a class declaration, it declares "static member functions" which belong to the class scope and have the same access to class instances as non-static member functions do, but are not invoked on objects (do not have the implicit this parameter). Class data members marked static have a single class-wide instance; they are not instantiated per-object. (Unfortunately, they don't participate properly in inheritance like true object-oriented class variables, which can be overridden in a derived class to be instance or vice versa.)
In C++, a privacy similar to internal linkage can be achieved using an unnamed namespace rather than static. Namespaces make the internal/external linkage concept mostly an obsolete mechanism for C compatibility.
C++ involves extern in the special extern "LANG" syntax (e.g. extern "C").
static_cast is unrelated to static; what they have in common is "static" meaning "prior to program run time": static storage is determined prior to run time, and the conversion of a static casts is also determined at compile time (without run-time-type info).

storage duration of functions, structs, classes, enums, and unions

If global variables and objects have static storage duration and external linkage?
do functions have static storage duration and external linkage as well?
what about structs and classes and enumerators(has external linkage i know)/unions?
I figured they have no storage duration and have no linkage,but then i thought that (global)functions have external linkage by default,but in a class they have class scope do they have internal linkage or?
Storage duration and linkage are unrelated concepts.
Functions do not have "storage duration", since functions do not reside in storage. Only objects have storage duration. Types do not reside in storage either, which is why types do not have storage duration.
It is not correct to say that classes have no linkage in general. Named classes declared in namespace scope have external linkage. Member functions of classes with external linkage also have external linkage. Classes declared locally and nameless classes have no linkage.
Functions don't officially have a storage duration, but in essence they're static (i.e., every function exists for the entire duration of the program). They have internal linkage if you define them static or inside of an anonymous namespace, otherwise external linkage.
Storage class applies to an object, not a type definition like a class, struct or union. It's fairly common to have two objects of the same class, one with static storage duration, and another with auto storage duration.
Likewise, you could create one object with internal linkage and another with external linkage:
T x;
static T y;
The same goes for linkage of classes:
class X { }; // external linkage
namespace {
class Y {}; // internal linkage
};

Difference between static in C and static in C++??

What is the difference between the static keyword in C and C++?
The static keyword serves the same purposes in C and C++.
When used at file level (outside of a function), it sets the visibility of the item it's applied to. Static items are not visible outside of their compilation unit (e.g., to the linker). Their duration is the same as the duration of the program.
These file-level items (functions and data) should be static unless there's a specific need to access them from outside (and there's almost never a need to give direct access to data since that breaks the central tenet of encapsulation).
If (as your comment to the question indicates) this is the only use of static you're concerned with then, no, there is no difference between C and C++.
When used within a function, it sets the duration of the item. Again, the duration is the same as the program and the item continues to exist between invocations of that function.
It does not affect the visibility of that item since it's visible only within the function. An example is a random number generator that needs to keep its seed value between invocations but doesn't want that value visible to other functions.
C++ has one more use, static within a class. When used there, it becomes a single class variable that's common across all objects of that class. One classic example is to store the number of objects that have been instantiated for a given class.
As others have pointed out, the use of file-level static has been deprecated in favour of unnamed namespaces. However, I believe it'll be a cold day in a certain warm place before it's actually removed from the language - there's just too much code using it at the moment. And ISO C have only just gotten around to removing gets() despite the amount of time we've all known it was a dangerous function.
And even though it's deprecated, that doesn't change its semantics now.
The use of static at the file scope to restrict access to the current translation unit is deprecated in C++, but still acceptable in C.
Instead, use an unnamed namespace
namespace
{
int file_scope_x;
}
Variables declared this way are only available within the file, just as if they were declared static.
The main reason for the deprecation is to remove one of the several overloaded meanings of the static keyword.
Originally, it meant that the variable, such as in a function, would be given storage for the lifetime of the program in an area for such variables, and not stored on the stack as is usual for function local variables.
Then the keyword was overloaded to apply to file scope linkage. It's not desirable to make up new keywords as needed, because they might break existing code. So this one was used again with a different meaning without causing conflicts, because a variable declared as static can't be both inside a function and at the top level, and functions didn't have the modifier before. (The storage connotation is totally lost when referring to functions, as they are not stored anywhere.)
When classes came along in C++ (and in Java and C#) the keyword was used yet again, but the meaning is at least closer to the original intention. Variables declared this way are stored in a global area, as opposed to on the stack as for function variables, or on the heap as for object members. Because variables cannot be both at the top level and inside a class definition, extra meaning can be unambiguously attached to class variables. They can only be referenced via the class name or from within an object of that class.
It has the same meaning in both languages.
But C++ adds classes. In the context of a class (and thus a struct) it has the extra meaning of making the method/variable class members rather members of the object.
class Plop
{
static int x; // This is a member of the class not an instance.
public:
static int getX() // method is a member of the class.
{
return x;
}
};
int Plop::x = 5;
Note that the use of static to mean "file scope" (aka namespace scope) is only deoprecated by the C++ Standard for objects, not for functions. In other words,:
// foo.cpp
static int x = 0; // deprecated
static int f() { return 1; } // not deprecated
To quote Annex D of the Standard:
The use of the static keyword is
deprecated when declaring objects in
namespace scope.
You can not declare a static variable inside structure in C... But allowed in Cpp with the help of scope resolution operator.
Also in Cpp static function can access only static variables but in C static function can have static and non static variables...😊