Что значит "правда"? или "10;" заявление означает в C ++ и как его можно использовать? - PullRequest
8 голосов
/ 09 июля 2009

В C ++ можно написать любое из следующих утверждений:

10;
true;
someConstant; //if this is really an integer constant

или что-то вроде

int result = obtainResult();
result; // looks totally useless

Последний может использоваться для подавления предупреждения компилятора «Переменная инициализирована, но на нее не ссылаются» (C4189 в VC ++), если макрос, который в некоторой конфигурации раскрывается в пустую строку, позже используется с переменной result. Как это:

int result = obtainResult();
result;
assert( result > 0 ); // assert is often expanded into an empty string in Release versions of code

В чем смысл таких утверждений? Как их можно использовать, кроме подавления предупреждений компилятором?

Ответы [ 9 ]

26 голосов
/ 09 июля 2009

Этот тип утверждений является логическим расширением того, как работают другие части языка. Подумайте о том, чтобы иметь функцию, которая возвращает значение, например int foo(), что также имеет некоторые побочные эффекты. Иногда вы хотите, чтобы эти побочные эффекты имели место, поэтому вы пишете foo(); как утверждение.

Теперь, хотя это не выглядит точно так же, как 10;, вызов функции рано или поздно оценивается как int, и с этим int ничего не происходит, как с 10;.

Другим примером той же проблемы является то, что, поскольку вы можете сделать a = b = 10;, это означает, что b = 10 должно вычислять до 10, следовательно, вы не можете выполнять присваивание без генерации значения, которое должно подавляться. *

Возможность записывать такие значения как операторы - это просто логический способ построения языка, но для представленных вами случаев может быть даже неплохо предупредить его компилятором.

Если вы не используете его для подавления предупреждений компилятора;)

7 голосов
/ 09 июля 2009

Эти операторы (называемые выражениями-выражениями в грамматике C ++) действительны, потому что они являются выражениями.

Выражения - это все конструкции, которые вычисляют какое-то значение, например

  • 3 + 5
  • someVariable
  • someFunctionCall (2)
  • someVar + = 62
  • val> 53

Я думаю, чтобы сохранить простоту грамматики, они решили не делать различий между теми выражениями, которые фактически имеют побочный эффект (например, вызов функции или присваивание) и теми, которые не имеют.

3 голосов
/ 09 июля 2009

Такое утверждение ничего не делает и, скорее всего, будет оптимизировано любым приличным компилятором.

Это может быть полезно для избавления от предупреждения неиспользуемая переменная , но с некоторыми компиляторами вы можете получить оператор без эффекта предупреждение вместо этого.

1 голос
/ 09 июля 2009

Они не имеют практического применения, кроме подавления предупреждений компилятором, и, как правило, компилятор исключает любое такое утверждение с постоянным значением, которое не имеет побочного эффекта.

0 голосов
/ 09 июля 2009

Я согласен с ответом Магнуса. Но есть одна вещь, которая меня озадачивает: почему вы используете эту ерунду

int result = obtainResult();
result; // looks totally useless

чтобы избавиться от предупреждений компилятора? По моему скромному мнению, в такой ситуации гораздо хуже не предупреждать. Переменная result до сих пор не используется - вы только что "подметали грязь под ковром". Этот подход «одиночная переменная» выглядит так, как будто чего-то не хватает ( Я случайно что-то удалил? ). Почему бы вам не использовать

(void)obtainResult();

на первом месте? Любой, кто будет читать ваш код, уверяет, что вас не волнует возвращаемый результат. Это очень трудно выразить "случайно". Очевидно, что это не генерирует никаких предупреждений компилятора.

0 голосов
/ 09 июля 2009

В некоторых встроенных средах доступ к регистру только для чтения будет иметь побочные эффекты, например очистить его.

Запись int temp = IV; очистка вызывает предупреждение, потому что temp не используется, и в этом случае я пишу IV;

0 голосов
/ 09 июля 2009

В C и C ++ оператор, который является просто выражением, оценивается.

Тот факт, что выражение может быть бесполезным, безвреден, а при включенном оптимизаторе может вообще не генерироваться код. Однако, как вы заметили, обычно это считается как использование переменной.

Обратите внимание, что операторы, содержащие только выражения, довольно распространены. Например, простой вызов функции. В printf("hello, world.\n"); возвращаемое значение printf() игнорируется, но функция все еще вызывается и происходит ее ожидаемый эффект (вывод текста).

Кроме того, присваивание переменной x = 3; также является оператором, состоящим из простого выражения, поскольку присваивание является оператором и возвращает значение в дополнение к побочному эффекту изменения lvalue.

0 голосов
/ 09 июля 2009

Это выражения, которые будут оцениваться при условии, что компилятор их не оптимизирует. Что касается «значения», я не уверен, что вы «подразумеваете» под этим!

0 голосов
/ 09 июля 2009

Хотя это и законно, я думаю, что эти заявления сбивают с толку и их следует избегать, даже для подавления предупреждений. Для меня более разумно подавить предупреждение, используя что-то вроде этого:

int result = 0;
result = obtainResult();
assert (result > 0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...