当前位置: C语言 -- 基础 -- 声明

声明(九)

5、_Atomic关键词

ISO/IEC 9899:2024标准中原子类型是可选特性;如果实现定义了宏__STDC_NO_ATOMICS__,实现不需要提供<stdatomic.h>头文件,也不需要支持<stdatomic.h>头文件的任何功能;这种情况下应不使用_Atomic关键词。


_Atomic关键词具有以下两种语法格式:

_Atomic ( type-name )
_Atomic type-name

其中type-name是类型名。第一种格式中_Atomic关键词是原子类型说明符,例如:_Atomic (int);第二种格式中_Atomic关键词是类型限定符,例如:_Atomic int


原子类型说明符中的类型名不能是数组类型、函数类型、原子类型或者限定类型。

typedef int Arr[5];
typedef int Func(int);

_Atomic (Arr) arr;		//非法。Arr是数组类型。
_Atomic (Func) func;		//非法。Func是函数类型。
_Atomic (atomic_int) ai;	//非法。atomic_int是原子类型。
_Atomic (const int) ci;	//非法。const int是限定类型。

与原子类型关联的特性仅对左值表达式有意义。


_Atomic关键词用作类型限定符时,限定的类型不能是数组类型或者函数类型。

typedef int Arr[5];
typedef int Func(int);

_Atomic Arr arr;	//非法。Arr是数组类型。
_Atomic Func func;	//非法。Func是函数类型。

_Atomic关键词用作类型限定符时,可以与其它类型限定符一起使用,结果类型是限定的原子类型;与其它类型限定符不同的是,相同类型的原子限定版本可能具有不同的大小、对齐方式和对象表示。

_Atomic const int *ptr; //等价于const atomic_int *ptr;。

以下代码中三个指针都是指向_Atomic const int类型对象的指针。

const _Atomic(int) *p1; //_Atomic(int)是类型说明符。
_Atomic const int *p2;  //_Atomic是类型限定符。
const atomic_int *p3;   //atomic_int是原子类型名,等价于_Atomic int。

6、typeof说明符

typeof运算符和typeof_unqual运算符统称为typeof类运算符,typeof类运算符语法格式如下所示:

typeof ( expression )
typeof ( type-name )
typeof_unqual ( expression )
typeof_unqual ( type-name )

其中expression是表达式,但不能是位字段表达式;type-name是类型名。


如果typeof类运算符的操作数是表达式,将得到表达式的类型;如果typeof类运算符的操作数是数组类型或者函数类型的形式参数,将得到转换后的指针类型。

int i = 0;
const int ci = 0;

typeof(i) i1 = 1;	//等价于int i1 = 1;。
typeof(ci) ci1 = 1;	//等价于const int ci1 = 1;。

如果typeof类运算符的操作数是可变修改类型(variably modified type),操作数会被评估;否则操作数不会被评估。

int n = 3;
int arr[n];

typeof(arr) a;  //等价于int a[3];。
typeof(n=5) i;  //表达式n=5不会被评估,n的值仍然为3。

变长数组的评估发生在程序执行期间,而不是在程序编译期间。


如果typeof类运算符的操作数是类型名,将得到类型名指定的类型。

typeof(int) i1 = 1;		//等价于int i1 = 1;。
typeof(const int) ci1 = 1;	//等价于const int ci1 = 1;。

如果typeof类运算符的操作数是typeof说明符,则先评估操作数,再评估当前typeof类运算符。这种情况可以递归发生,直至操作数不再是typeof说明符。

int i = 0;
const int ci = 0;

typeof(typeof(ci)) a = 1;	//等价于const int a = 1;。
typeof(const typeof(i)) b = 1;	//等价于const int b = 1;。

嵌套的typeof运算符内,不会执行数组到指针的衰减(array to pointer decay)。

typeof(typeof(int [4])) arr;  //等价于int arr[4];。

typeof运算符保留操作数的所有类型限定符;typeof_unqual运算符的运算结果是typeof运算符结果类型的非原子非限定版本。

const int ci = 0;

typeof(ci) a = 1;		//等价于const int a = 1;。
typeof_unqual(ci) b = 1;	//等价于int b = 1;。

如果typeof类运算符的操作数具有_Atomic (type-name)格式,_Atomic视为是类型限定符。