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