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, and enum definitions

    • Names 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

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

  • Initialized at the first call of the code fragment in which it is contained

  • Usable with all variables (regardless of where they were declared)"

In a block
Outside a block

Static storage duration

Static storage duration

Block scope

File scope

No linkage

Internal linkage

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).

In a block
Outside a block

Static storage duration

Automatic storage duration

Block scope

File scope

External linkage

External linkage

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

It allows the function to be called from other files

  • External linkage

static

It limits the use of the function name to the file in which it is defined

Type qualifiers

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

Opposite of register

  • For a variable declared as volatile, we ask the compiler not to perform any optimization on it

  • And to keep the variable in CPU registers only as long as strictly necessary for the operations being performed

Reasons for using 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

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.

Advantages
Disadvantages

The compiler can perform all optimizations it deems appropriate.

The compiler does not verify if the programmer creates aliasing pointers.

Last updated