Почему (void) sizeof (param) не «использует» пары?

У меня есть макрос, определенный следующим образом:

#define UNREF_PARAM_1(a)
do { \
(void)sizeof(a); \
} \
while (0)

Избавиться от предупреждений компилятора. В новом проекте, над которым я работаю, VS2013 неожиданно снова жалуется на не имеющий ссылки формальный параметр.

Странно это работает, если я просто использую (void)param,
Кто-нибудь знает, почему он не работает при использовании с (void)sizeof(param)?

4

Решение

Потому что в sizeof(param), param это так называемый неоцененный операнд и, следовательно, не используется odr — то есть не требуется во время выполнения.

Тем не мение, (void)param действительно составляет использование odr.

Приведение с нотацией в вашем коде внутренне вызывает static_cast, [Expr.static.cast] / 6:

Любое выражение может быть явно преобразовано в тип резюме void, в
в этом случае оно становится выражением отброшенного значения (пункт 5).

[Выражение] / 10:

В некоторых контекстах выражение появляется только для его побочных эффектов. Такое выражение называется выражение отброшенного значения. Выражение вычисляется и его значение отбрасывается. […] Преобразование lvalue-to-rvalue (4.1) применяется, только если выражение является lvalue типа volatile-квалифицированного […]

[Basic.def.odr] / 2:

Выражение потенциально оценивается если это не оцененный операнд (пункт 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)?
7

Другие решения


По вопросам рекламы [email protected]