编译器抱怨,当简单地执行强制转换为 void 时,使用了未使用的变量

问题描述 投票:0回答:1

我们刚刚发现某个编译器(Greenhills)将以下构造视为错误:

// local variable
mytype x;
...
((void) (x));

编译器报告:

error #549-D: variable "x" is used before its value is set

我们在特殊情况下使用此类构造,以避免与根本未使用的变量相关的编译器警告。我们想测试该类型是否真的存在,所以这完全是有意为之。

然而,我的问题与该编译器的行为方式有关。根据什么 C 标准规则,编译器决定强制转换为 void(实际上应该在汇编代码中转换为空)实际上是在“使用”变量?

c compiler-errors casting unused-variables greenhills
1个回答
0
投票

C 标准 C17 6.3.2.2。说道:

void 表达式(具有类型

void
的表达式)的(不存在的)值不应 以任何方式使用,并且隐式或显式转换(除了
void
)不得 应用于这样的表达式。如果任何其他类型的表达式被计算为 void 表达式,其值或指示符被丢弃。 (对 void 表达式进行求值 副作用。)

所以大多数时候这个表达方式根本不被使用。然而,括号中的最后一句话很有趣 - 评估副作用意味着例如如果您有一个函数作为操作数,则该函数将被执行。或者,如果您有一个

volatile
限定变量,编译器必须计算该表达式。
(void)my_volatile;
是否应该被视为读取访问一直是个模糊的问题。

我们可以肯定地说,如果

mytype
不涉及
volatile
那么编译器就会感到困惑,应该丢弃整行。但如果是
volatile
那么可能涉及读取访问。

然而编译器仍然不应该对

volatile
是否已初始化做出任何假设,因为
volatile
的定义就是变量可能会在编译器无法控制的情况下随时发生变化。所以它仍然是一个不正确的诊断消息。

我会将其报告为编译器诊断错误,因为强制转换为

void
是常见的 C 习惯用法。


在即将推出的 C23 中,您将能够将变量声明为

[[maybe_unused]] mytype x;
,这也应该消除编译器警告。

© www.soinside.com 2019 - 2024. All rights reserved.