Declaration specifiers

declaration_specifiers declaretor;
where:
declarator
: name of the declared variable (it can also include *, (), []).declaration_specifiers
: properties of the variables or functions being declared, and they fall into three categories:Storage Class At most one storage class can appear (It must appear as the first specifier).
Type Qualifiers There can be zero or more type qualifiers.
Type Specifiers
These are the keywords:
void
,char
,short
,int
,long
,float
,double
,unsigned
,signed
struct
,union
, andenum
definitionsNames created with typedef are also included
Pointer types are considered here as well
Example:
static int n = 0;
const float f = 2.1
Variable properties
Here's the English translation of your detailed explanation:
Storage Duration ➡️ Reference to Execution
The portion of execution during which the variable exists. It determines when memory is allocated for the variable and when it is released.
Automatic Variable (in the Activation Record)
Allocated when the surrounding block is executed.
Deallocated when the block ends (thus losing the value held by the variable).
Static Variable (in the DATA segment) Remains in the same memory location for the entire execution of the program (the value is preserved).
Scope ➡️ Reference to Program
The portion of code within which a variable can be referred to by its name.
Block Scope (local variable) The variable is visible from its declaration to the end of the block (delimited by
{}
).File Scope (global variable) The variable is visible from its declaration to the end of the file that contains it.
Linkage
It determines the extent to which a variable can be shared across different parts of the program.
External Linkage The variable can be shared across multiple files of the program.
Internal Linkage The variable is restricted to a single file (but can be shared among all functions in that file).
No Linkage The variable belongs to a single function and cannot be shared.
Default properties
Variables declared within a block (including the body of a function) automatic storage duration, block scope, and no linkage
Variables declared outside any block (at the outermost level of the program) static storage duration, file scope, and external linkage
Storage classes
auto
auto
Applicable only to variables that belong to a block
Automatic storage duration
Block scope
No linkage
It is never explicitly specified because it is already used by default in blocks.
static
static
Initialized at the first call of the code fragment in which it is contained
Usable with all variables (regardless of where they were declared)"
Static storage duration
Static storage duration
Block scope
File scope
No linkage
Internal linkage
extern
extern
It is used when referring to variables defined in other files (usually source files)
it Tells the compiler that the variable is already defined in another source file and to refer to that one
No memory is allocated for the variable with the extern attribute (because memory has already been allocated in the file where it is defined)
For an array, it is not necessary to specify the size during declaration (because it has already been defined in another file).
Static storage duration
Automatic storage duration
Block scope
File scope
External linkage
External linkage
register
register
It asks the compiler to store the variable in a register instead of main memory (since register is a request, the compiler may still store the variable in memory).
Applicable only to variables declared within a block
It has the properties of an automatic variable
The only difference from automatic variables is that the address-of operator (&) cannot be used on it (even if the variable is actually stored in memory).
Storage classes of a function
extern
extern
It allows the function to be called from other files
External linkage
static
static
It limits the use of the function name to the file in which it is defined
Type qualifiers
const
const
Read-only variable (R-value)
A variable declared as const cannot be modified by the program (the compiler detects all direct attempts to modify the variable)
More readable code (the programmer knows that the variable cannot be changed)
Helps the compiler catch potential errors by indicating that the variable’s value is not meant to be changed
In certain types of applications (e.g., embedded systems) the compiler can use the const keyword to identify data stored in ROM
const vs #define
const
#define
Can be used with any type of variable
For numeric constants, character constants, or string literals
const
variables follow the usual scope rules
Does not define variables, only constant values
The value of a const
variable can be inspected by a debugger
Cannot be inspected by a debugger
const
variables cannot be used in constant expressions
If I defined:
const int n = 10;
I cannot create an array with it:
int a[n];
Macros can be used in constant expressions
You can apply the address-of operator (&
) to const variables (because they have a memory address)
Macros are not variables, so they do not have an address
volatile
volatile
Opposite of register
For a variable declared as
volatile
, we ask the compiler not to perform any optimization on itAnd to keep the variable in CPU registers only as long as strictly necessary for the operations being performed
Reasons for using volatile
volatile
In some cases, it is useful to define variables whose modification timing is uncertain during the production phase.
The modification can be due to several factors:
The variable is updated by external code This could be due to an interrupt or some thread controlling operations, often used to directly interface with hardware.
The variable is updated by code called by a timer A timer can trigger a piece of code that updates the same variable.
The variable is updated by multiple threads concurrently In a multi-threaded environment, a variable may be accessed and updated by more than one thread at the same time.
restrict
restrict
C99 ➡️ restrict
can be applied only to pointers (restricted pointers)
Pointer alias of another pointer A pointer that points to the same memory area as another pointer.
restrict
tells the compiler that the programmer guarantees no aliasing of pointers. This means the programmer ensures that no other pointer will refer to the same memory location as the restricted pointer.
The compiler can perform all optimizations it deems appropriate.
The compiler does not verify if the programmer creates aliasing pointers.
Last updated