| Pointer | ||||
| Array | ||||
| Bit-field | ||||
| Atomic types(C11) | ||||
(C23) | ||||
(C99) | ||||
| Alignment specifiers | ||||
| Storage duration and linkage | ||||
| External and tentative definitions | ||||
| Static assertions | ||||
| Attributes(C23) |
Specifystorage duration andlinkage of objects and functions:
auto - automatic duration and no linkageregister - automatic duration and no linkage; address of this variable cannot be takenstatic - static duration and internal linkage (unless at block scope)extern - static duration and external linkage (unless already declared internal)
| (since C11) |
Contents |
Storage-class specifiers appear indeclarations andcompound literal expressions(since C23). At most one specifier may be used, except that_Thread_local(until C23)thread_local(since C23) may be combined withstatic orextern to adjust linkage(since C11). The storage-class specifiers determine two independent properties of the names they declare:storage duration andlinkage.
_Alignas(until C23)alignas(since C23)(since C11), andregister arrays are not convertible to pointers.5)_Thread_local(until C23)thread_local(since C23) indicatesthread storage duration. It cannot be used with function declarations. If it is used on a declaration of an object, it must be present on every declaration of the same object. If it is used on a block-scope declaration, it must be combined with eitherstatic orextern to decide linkage. | (since C11) |
If no storage-class specifier is provided, the defaults are:
For any struct or union declared with a storage-class specifier, the storage duration (but not linkage) applies to their members, recursively.
Function declarations at block scope can useextern or none at all. Function declarations at file scope can useextern orstatic.
Function parameters cannot use any storage-class specifiers other thanregister. Note thatstatic has special meaning in function parameters of array type.
Everyobject has a property calledstorage duration, which limits the objectlifetime. There are four kinds of storage duration in C:
| (since C11) |
Linkage refers to the ability of an identifier (variable or function) to be referred to in other scopes. If a variable or function with the same identifier is declared in several scopes, but cannot be referred to from all of them, then several instances of the variable are generated. The following linkages are recognized:
extern have this linkage, as well as all function parameters and all identifiers that aren't functions or variables.staticorconstexpr(since C23) have this linkage, and all file scope functions declaredstatic (static function declarations are only allowed at file scope).static orconstexpr(since C23) have this linkage, all file scope function declarations which are not declaredstatic, all block scope function declarations, and, additionally, all variables or functions declaredextern have this linkage unless a prior declaration with internal linkage is visible at that point.If the same identifier appears with both internal and external linkage in the same translation unit, the behavior is undefined. This is possible whententative definitions are used.
| This section is incomplete Reason: should this be a separate top-level entry in c/language under Miscellaneous? |
Declarations with external linkage are commonly made available in header files so that all translation units that#include the file may refer to the same identifier that are defined elsewhere.
Any declaration with internal linkage that appears in a header file results in a separate and distinct object in each translation unit that includes that file.
Library interface, header file "flib.h":
#ifndef FLIB_H#define FLIB_Hvoid f(void);// function declaration with external linkageexternint state;// variable declaration with external linkagestaticconstint size=5;// definition of a read-only variable with internal linkageenum{ MAX=10};// constant definitioninlineint sum(int a,int b){return a+ b;}// inline function definition#endif // FLIB_H
Library implementation, source file "flib.c":
#include "flib.h" staticvoid local_f(int s){}// definition with internal linkage (only used in this file)staticint local_state;// definition with internal linkage (only used in this file) int state;// definition with external linkage (used by main.c)void f(void){ local_f(state);}// definition with external linkage (used by main.c)
Application code, source file "main.c":
#include "flib.h" int main(void){int x[MAX]={size};// uses the constant and the read-only variable state=7;// modifies state in flib.c f();// calls f() in flib.c}
auto,register,static,extern,_Thread_localthread_local
The keyword_Thread_local is usually used through the convenience macrothread_local, defined in the header<threads.h>. | (until C23) |
Thetypedef andconstexpr(since C23) specifiers are formally listed as storage-class specifiers in the C language grammar, but do not specify storage.
The auto specifier is also used for type inference. | (since C23) |
Names at file scope that areconst and notextern have external linkage in C (as the default for all file-scope declarations), but internal linkage in C++.
#include <stdio.h>#include <stdlib.h> // static storage durationint A; int main(void){printf("&A = %p\n",(void*)&A); // automatic storage durationint A=1;// hides global Aprintf("&A = %p\n",(void*)&A); // allocated storage durationint* ptr_1=malloc(sizeof(int));// start allocated storage durationprintf("address of int in allocated memory = %p\n",(void*)ptr_1);free(ptr_1);// stop allocated storage duration}
Possible output:
&A = 0x600ae4&A = 0x7ffefb064f5caddress of int in allocated memory = 0x1f28c30
C++ documentation forStorage class specifiers |