为什么(void)sizeof(param)没有"使用"param?

Chr*_*ris 4 c++ compiler-warnings suppress-warnings visual-studio language-lawyer

我有一个宏定义如下:

#define UNREF_PARAM_1(a)
    do { \
        (void)sizeof(a); \
    } \
    while (0)
Run Code Online (Sandbox Code Playgroud)

摆脱编译器警告.在我正在开展的一个新项目中,VS2013突然再次抱怨一个未引用的形式参数.

奇怪的是,如果我只是使用它确实有效(void)param.有没有人知道为什么它与它一起使用时不起作用(void)sizeof(param)?

Col*_*mbo 7

因为sizeof(param),param是所谓的未计算的操作数,因此不能ODR使用的-也就是说,没有必要在运行时.

但是,(void)param确实构成了一种使用.

代码中内含符号的强制转换调用内部调用static_cast.[expr.static.cast]/6:

任何表达式都可以显式转换为cv 类型void,在这种情况下,它将成为废弃值表达式(第5条).

[EXPR]/10:

在某些情况下,表达式仅出现其副作用.这种表达式称为丢弃值表达式.计算表达式并丢弃其值.[...] 仅当表达式是volatile限定类型的左值时才应用左值到右值转换(4.1) [...]

[basic.def.odr]/2:

除非是未评估的操作数(第5条)或其子表达式,否则可能会对表达式进行求值.名称显示为潜在评估表达式的变量是odr-used, 除非它是满足出现在常量表达式(5.19)中的要求的对象,并且立即应用左值到右值转换(4.1).

该引用的第一部分指出,这sizeof(a)不是一个odr用途,a因为a是一个未评估的操作数1.
显然(void)a可能会被评估.并且因为a当然既不允许出现在常量表达式中也不被声明volatile,所以没有"立即应用"左值到右值的转换,因此使用的a是odr.


1)这是一个表达式列表,其中x是来自C++ 11的未评估操作数:

  • typeid(x),其中x不是多态类类型的glvalue
  • sizeof(x)(和sizeof x)
  • noexcept(x)
  • decltype(x)
  • alignof(x)?alignas(x)?