Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么(void)sizeof(param)不是;使用;波拉姆?_C++_Visual Studio_Language Lawyer_Compiler Warnings_Suppress Warnings - Fatal编程技术网

C++ 为什么(void)sizeof(param)不是;使用;波拉姆?

C++ 为什么(void)sizeof(param)不是;使用;波拉姆?,c++,visual-studio,language-lawyer,compiler-warnings,suppress-warnings,C++,Visual Studio,Language Lawyer,Compiler Warnings,Suppress Warnings,我有一个宏定义如下: #define UNREF_PARAM_1(a) do { \ (void)sizeof(a); \ } \ while (0) 以消除编译器警告。在我正在从事的一个新项目中,VS2013突然再次抱怨一个未引用的形式参数 奇怪的是,如果我只使用(void)param,它确实可以工作。 有人知道为什么它在与(void)sizeof(param)一起使用时不起作用吗?因为在sizeof(param)中,param是一个所谓的未赋值操作数

我有一个宏定义如下:

#define UNREF_PARAM_1(a)
    do { \
        (void)sizeof(a); \
    } \
    while (0)
以消除编译器警告。在我正在从事的一个新项目中,VS2013突然再次抱怨一个未引用的形式参数

奇怪的是,如果我只使用
(void)param
,它确实可以工作。 有人知道为什么它在与
(void)sizeof(param)
一起使用时不起作用吗?

因为在
sizeof(param)
中,
param
是一个所谓的未赋值操作数,因此没有使用odr,也就是说,在运行时不需要

但是,
(void)param
确实构成odr使用。

代码中带有符号的强制转换在内部调用
静态\u强制转换
。[expr.static.cast]/6:

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

[expr]/10:

在某些上下文中,表达式仅因其副作用而出现。这样的表达式称为丢弃值表达式。表达式将被求值,其值将被丢弃。[…]只有当表达式是volatile限定类型的左值时,才会应用左值到右值的转换(4.1)[…]

[basic.def.odr]/2:

除非表达式是未赋值的操作数(第5条)或其子表达式,否则表达式可能被求值。一个变量,其名称显示为可能计算的 表达式使用odr,除非它是满足 出现在常数表达式(5.19)中的要求以及 立即应用左值到右值的转换(4.1)

此引号的第一部分指定
sizeof(a)
不是
a
的odr用法,因为
a
是未计算的操作数1。
显然,
(void)a
可能会被评估。由于
a
肯定既不允许出现在常量表达式中,也不允许声明为
volatile
,因此不会“立即应用”左值到右值的转换,因此使用了
a


1) 下面是一个表达式列表,其中
x
是C++11中未计算的操作数:

  • typeid(x)
    ,其中
    x
    不是多态类类型的值
  • sizeof(x)
    (和
    sizeof x
  • noexcept(x)
  • decltype(x)
  • alignof(x)
    <代码>对齐方式(x)

sizeof
在编译时进行计算。我通常避免使用此类宏,因为随着时间的推移,代码会发生变化,人们会忘记删除它们。我的首选方法是在函数头中注释掉参数的名称,这会抑制警告,并使在不更新代码的情况下无法开始使用参数。我将此宏用于调试生成,其中我希望某些函数不做任何操作,也不获取有关未引用参数的警告。现在,我在(a)的(void)大小之前添加了一个_pragma(warning(suppress:4100));指示