当前位置: 首页 > 知识库问答 >
问题:

为什么“volatilequalifiedxpr volatilequalifiedxpr”在C中不一定是UB,而是在C中?

桑宇
2023-03-14

当我今天阅读C标准时,它提到了副作用

访问易失性对象、修改对象、修改文件或调用执行任何这些操作的函数都是副作用

C标准说

访问易失性glvalue(3.10)指定的对象、修改对象、调用库I/O函数或调用执行任何这些操作的函数都是副作用

因此,因为两者都禁止在同一个标量对象上发生未排序的副作用,所以C允许以下内容,但C使其成为未定义的行为

int a = 0;
volatile int *pa = &a;

int b = *pa + *pa;

我是否正确阅读了规格?如果存在差异,原因是什么?

共有1个答案

李云
2023-03-14

在这方面,我认为C和C之间没有有效的变化。虽然排序的措辞不同,但最终结果是相同的:两者都会导致未定义的行为(虽然C似乎表示评估将成功,但结果未定义)。

在C99(抱歉,手边没有C11)中,第5.1.2.3.5段规定:

-在序列点,挥发性对象是稳定的,因为以前的访问已经完成,后续的访问尚未发生。

结合您在5.1.2.3.2中的引用,将表明pa的值对于pa的至少一个访问不会处于稳定状态。这是合乎逻辑的,因为编译器将被允许以任何顺序评估它们,只需一次,或同时(如果可能的话)。然而,它实际上并没有定义稳定的含义。

在C 11中,在1.9.13处显式引用了未排序的操作。然后第15点表示对同一操作数的此类未排序操作是未定义的。由于未定义的行为可能意味着任何事情发生,因此它可能比C的不稳定行为强。但是,在这两种情况下,您的表达式都没有保证结果。

 类似资料:
  • 我正在尝试执行GET命令,以便我可以从服务器获取数据。下面的Curl适用于Postman。 在运行我的代码时,我能够获取会话ID。下一步是获取数据。但是当我执行GET时,我没有得到任何响应。相反,我得到一个错误,如下所示:“指定的值具有无效的HTTP标头字符。(参数'name')” 下面是我试图执行的C代码 问题:我没有收到来自服务器的响应,响应长度为零。 以下是答案:0 回答ErrorMessa

  • 使用C++20的时,我注意到似乎不能满足概念。根据的定义,在C++20中应该实现以下功能: 这个需求应该实现与的对称比较--根据我的理解,这足以满足。 奇怪的是,这个问题似乎在所有主要编译器上都是一致的。以下代码将从Clang、GCC和msvc中拒绝: 联机尝试 但是,接受与相同的断言: 联机尝试 除非我误会了什么,这似乎是个窃听器。我的问题是,这是三个编译器实现中的一个巧合的bug,还是C++2

  • sizeof(char)和sizeof(bool)都等于1(在我的编译器/系统/whatever中,我听说它并不总是相同的值),一个bool只能存储true或false,而char可以接受更多的值,并且可以使用按位运算符充当多个bool变量(8位,每个位可以用作1 bool共8个bool) 那么使用bool而不是char有什么好处吗? 那么除了可读性,还有别的吗?我在某处读到,int比short或

  • 在Julia中,打印格式化字符串的语法如下: 为什么是宏而不是函数?这样它就可以接受不同数量的参数了吗?

  • 但是得到了错误:

  • 主要内容:C# 强大的编程功能,C#发展史C# 的发音为“C Sharp”,是一门由微软开发并获得了 ECMA(欧洲计算机制造商协会)和 ISO(国际标准组织)批准的现代的、通用的、面向对象的编程语言。 C# 由 Anders Hejlsberg 及其团队在《 .Net Framework》的开发过程中开发,属于 .Net Framework 的一部分,可以用来编写 .Net 应用程序。C# 是专为 CLI (公共语言基础结构)设计的,C