仅包含标识符的表达式是否会读取volatile变量?

det*_*tly 0 c standards volatile

我正在使用Microchip的编译器编写微控制器(dsPIC24).外围设备都是内存映射变量.偶尔有必要通过读取来清除缓冲区,我通常只做:

SPI1BUF;
Run Code Online (Sandbox Code Playgroud)

... 在Microchip的标题中SPI1BUF声明volatile char了哪里.它适用于我,但现在我很好奇:它是标准化的行为吗?我记得如果我执行任务:

unsigned char x = SPI1BUF;
Run Code Online (Sandbox Code Playgroud)

......标准说必须读取volatile变量.但对于标识符整体表达式情况,这也是如此吗?

caf*_*caf 5

这样的裸表达式是C标准中称为"表达式语句"的语句类型.标准的相关部分(6.8.3)说:

表达式语句中的表达式被计算为其副作用的void表达式.

读取一个volatile合格变量的值被认为是一种副作用,因此根据§5.1.2.3,它不能被省略:

访问易失性对象,修改对象,修改文件或调用执行任何这些操作的函数都是副作用,这些都是执行环境状态的变化.

假设SPI1BUF是一个左值(这是真的既,如果它是一个标识符,或者扩展到一元的调用宏*操作者),§6.3.2.1已经这样说的:

除非它是运算sizeof符的操作数,一元& 运算符,运算符,++运算--符或运算符的左操作数.或赋值运算符,否则将没有数组类型的左值转换为存储在指定对象中的值(并且不再是左值).

由于没有例外适用,这可以确保底层(易变)对象是"访问",因为左值已经转换为存储在对象中的值,这显然需要访问该对象的值.

总结:是的,这是标准行为.