类型限定符

类型限定符为标识符提供两个属性之一。 const 类型限定符将对象声明为不可修改。 volatile 类型限定符声明一个项,该项的值可由超出该项所在的程序控制范围的某个项(如并发执行的线程)合理更改。

constrestrictvolatile 这几个类型限定符只能在声明中出现一次。 类型限定符可与任何类型说明符一起出现;但是,它们不能在多项声明中的第一个逗号的后面出现。 例如,以下声明是合法的:

typedef volatile int VI;
const int ci;

以下声明是非法的:

typedef int *i, volatile *vi;
float f, const cf;

仅当访问作为表达式的左值的标识符时,类型限定符才会相关。 有关左值和表达式的信息,请参阅左值表达式和右值表达式

语法

type-qualifier
const
restrict
volatile

constvolatile

以下是合法的 constvolatile 声明:

int const *p_ci;      // Pointer to constant int
int const (*p_ci);   // Pointer to constant int
int *const cp_i;     // Constant pointer to int
int (*const cp_i);   // Constant pointer to int
int volatile vint;     // Volatile integer

如果数组类型的规范包括类型限定符,则将限定元素而不是数组类型。 如果函数类型的规范包括限定符,则行为是不确定的。 volatileconst 都不会影响值的范围或对象的算术属性。

  • const 关键字可用于修改任何基本或聚合类型,或修改指向任何类型的对象的指针或 typedef。 如果某项声明为只包含 const 类型限定符,则其类型被视为 const int。可以初始化 const 变量,也可以将该变量置于存储的只读区域中。 const 关键字对于声明指向 const 的指针很有用,因为这要求函数不以任何方式更改指针。

  • 编译器假定可通过使用或修改 volatile 变量的值未知过程来访问该变量(在程序中的任意未知)。 无论在命令行上指定了哪些优化,都必须为 volatile 变量的每次赋值或引用生成代码,即使它看起来没有任何效果。

如果单独使用 volatile,则假定 intvolatile 类型说明符可用于提供对特定内存位置的可靠访问。 将 volatile 用于数据对象,这些对象可通过信号处理程序、并行执行程序或特定硬件(如内存映射的 I/O 控制寄存器)访问或更改。 可以为变量的生存期将变量声明为 volatile,也可以将单个引用强制转换为 volatile

  • 一个项可以同时是 constvolatile,在这种情况下,此项不能被它自己的程序以合法方式修改,但能被一些异步进程修改。

restrict

C99 中引入的 restrict 类型限定符(以 /std:c11/std:c17 模式提供)可应用于指针声明。 它限定指针,而不是它指向的内容。

restrict 是编译器的优化提示,当前作用域中没有其他指针引用相同的内存位置。 也就是说,只使用指针或从其派生的值(例如指针 + 1)在指针的生存期内访问对象。 这有助于编译器生成更多的优化代码。 C++ 具有等效机制 __restrict

请注意,restrict 是你与编译器之间的协定。 如果你对标记为 restrict 的指针使用了别名,则结果是不确定的。

下面是使用 restrict 的示例:

void test(int* restrict first, int* restrict second, int* val)
{
    *first += *val;
    *second += *val;
}

int main()
{
    int i = 1, j = 2, k = 3;
    test(&i, &j, &k);

    return 0;
}

// Marking union members restrict tells the compiler that
// only z.x or z.y will be accessed in any scope, which allows
// the compiler to optimize access to the members.
union z 
{
    int* restrict x;
    double* restrict y;
};

另请参阅

/std(指定语言标准版本)
声明和类型