c++ - 丢弃一个值会导致读取它吗?
问题描述
考虑以下示例:
{
int x;
(void)x; // silence the "unused" warning
...
}
x
由于未初始化读取,这是否会导致未定义的行为?如果是,那么这是否意味着在以下代码中必须由编译器发出内存读取指令(读取指针)?
volatile char* p=getP();
(void)*p;
我对这方面的 C 和 C++ 规则都感兴趣,以防它们不同。
解决方案
在 C++ 中,访问与左值到右值的转换相结合。这种转换需要一个“身份”并产生它的价值。关于丢弃值表达式的主题,C++ 标准是这样说的:
[expr](强调我的)
12在某些情况下,表达式的出现只是因为它的副作用。这样的表达式称为弃值表达式。不应用数组到指针和函数到指针的标准转换。当且仅当表达式是 volatile 限定类型的左值并且它是以下之一时,才应用左值到右值的转换:
- ( 表达式 ),其中表达式是这些表达式之一,
- 身份表达,
- 下标,
- 类成员访问,
- 间接,
- 指向成员的操作,
- 条件表达式,其中第二个和第三个操作数都是这些表达式之一,或者
- 逗号表达式,其中右操作数是这些表达式之一。
[注意:使用重载运算符会导致函数调用;以上仅涵盖具有内置含义的运算符。— 尾注] 如果在此可选转换之后表达式是纯右值,则应用临时实现转换。[ 注意:如果表达式是类类型的左值,它必须有一个 volatile 复制构造函数来初始化作为左值到右值转换的结果对象的临时对象。— 尾注] 对 glvalue 表达式求值并丢弃它的值。
在非易失性情况下,没有左值到右值的转换。因此,我们可以自信地说该变量未被访问。
但是,在 volatile 情况下,您在强制转换表达式内部具有间接性,并且会进行左值到右值的转换。因此,将读取 volatile ,并且您会从读取未初始化的对象中获得未定义的行为。
为了避免 volatile glvalues 周围的未定义行为,可以将相关变量注释为[[maybe_unused]]
. 这是认可的方式,也是我更喜欢在非易失性案例中使用演员的方式。
推荐阅读
- elm - 如何从 elm 对象中获取特定的键值对
- python - 如何在一个请求中收集所有可用的 Pod 指标
- sql - SQL如何查询总计和小计
- regex - 我的公式只保留一个单词,空格后没有任何内容
- javascript - 将每个对象属性乘以 2 并从结果中创建新对象
- javascript - 使用一个链接滚动两列
- linux - 从 LINUX 特定目录下的文件中查找特定字符串
- flutter - 如何更改 Flutter TextButton 的高度?
- python - 如何以编程方式生成不规则复数名词的单词列表?
- sql - 如何使用 mongodb 和 cubejs 格式化时间类型的数据?