У меня есть макрос, определенный следующим образом:
#define UNREF_PARAM_1(a)
do { \
(void)sizeof(a); \
} \
while (0)
Избавиться от предупреждений компилятора. В новом проекте, над которым я работаю, VS2013 неожиданно снова жалуется на не имеющий ссылки формальный параметр.
Странно это работает, если я просто использую (void)param
,
Кто-нибудь знает, почему он не работает при использовании с (void)sizeof(param)
?
Потому что в sizeof(param)
, param
это так называемый неоцененный операнд и, следовательно, не используется odr — то есть не требуется во время выполнения.
Тем не мение, (void)param
действительно составляет использование odr.
Приведение с нотацией в вашем коде внутренне вызывает static_cast
, [Expr.static.cast] / 6:
[Выражение] / 10:Любое выражение может быть явно преобразовано в тип резюме
void
, в
в этом случае оно становится выражением отброшенного значения (пункт 5).
[Basic.def.odr] / 2:В некоторых контекстах выражение появляется только для его побочных эффектов. Такое выражение называется выражение отброшенного значения. Выражение вычисляется и его значение отбрасывается. […] Преобразование lvalue-to-rvalue (4.1) применяется, только если выражение является lvalue типа volatile-квалифицированного […]
Выражение потенциально оценивается если это не оцененный операнд (пункт 5) или его подвыражение. Переменная, имя которой отображается как потенциально оцененная
выражение УСО используемый если это не объект, который удовлетворяет
требования к появлению в постоянном выражении (5.19) и
Преобразование lvalue в rvalue (4.1) применяется немедленно.
Первая часть этой цитаты указывает, что sizeof(a)
не использование одр a
поскольку a
это неоцененный операнд1.
очевидно (void)a
потенциально оценивается. И потому что a
безусловно, ни разрешено появляться в постоянном выражении, ни объявлено volatile
никакое преобразование lvalue в rvalue не «немедленно применяется» и, таким образом, a
используется odr.
1) Вот список выражений, где x
это неоцененный операнд с C ++ 11:
typeid(x)
, где x
не является типом полиморфного классаsizeof(x)
(а также sizeof x
)noexcept(x)
decltype(x)
alignof(x)
? alignas(x)
?