Пустой вызов функции как выражения - PullRequest
4 голосов
/ 29 июня 2019

Из стандарта C ясно, что вызовы общих функций являются выражениями из определения:

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

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

Но те, которые не возвращают значение, donкажется, не соответствуют этому определению.Само имя функции делает (так как оно обозначает функцию), но это не вызов функции.

Стандарт четко говорит, что вызов функции является выражением, и что он может возвращать void,но это, кажется, противоречит определению выражения.Чего мне не хватает?

Ответы [ 4 ]

4 голосов
/ 29 июня 2019

Вызов функции является выражением независимо от типа возвращаемого значения функции.Грамматика Си ортогональна его системе типов.Они являются независимыми частями языка.Грамматически func(); является оператором выражения .

expression_statement
    : ';'
    | expression ';'
    ;

postfix_expression
    : primary_expression
    | postfix_expression '[' expression ']'
    | postfix_expression '(' ')'
    | postfix_expression '(' argument_expression_list ')'

Есть очень мало вещей, которые вы можете сделать с результатом void.Вы не можете присвоить его переменной, поскольку void переменные не допускаются.Если результат func() равен void, вы можете использовать четыре оператора:

  • Скобки: (func())
  • Последовательность запятых: func(), 42
  • Ternaryоператор: 42 ? func() : func().
  • Приведение к пустоте: (void) func()

Вы также можете вернуть void результат:

return func();

Наконец, вfor(init; condition; increment) цикл, все три части являются выражениями. init и приращение (но не условие ) может быть void.

for (func(); 42; func()) { }

Немногие из них полезны, но ни один из них не годитсястиль, но все они законны.

3 голосов
/ 29 июня 2019

Пункт 1 пункта 6.5 не был полностью продуман в отношении void. Стандарт С несовершенен и имеет ряд недостатков. Этот абзац должен быть получен как общее описание, чтобы ориентировать читателей, и не является точной математической спецификацией выражения.

1 голос
/ 29 июня 2019

Говорят, что:

Выражение - это последовательность операторов и операндов, которые

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

Указывает, что вычисление значения является один среди возможностей.Вызов функции void будет таким, который «вызывает побочные эффекты».


Любое выражение в выражении выражения в C считается выражением void. C11 6.8.3 Выражения и нулевые выражения p2 :

Выражение в выражении выражения оценивается как выражение void для его побочных эффектов. 153)

153) Такие как назначения и вызовы функций, которые имеют побочные эффекты.

т.е. в выражении выражение

a = 5;

a = 5 является выражением void , которое оценивается только для его побочных эффектовто есть присвоение значения 5 в a, не для вычисления значения, даже если a = 5 может использоваться для вычисления значения в в других контекстах .Точно так же вы можете написать a;, и это законное использование выражения «оценивается по его побочным эффектам», даже если оно не имеет его.Здесь оно не перестает быть выражением.

LHS оператора запятой является пустым выражением.Выражение void можно использовать в ? : - тогда обе ветви будут выражениями void, а все выражение само по себе будет выражением void.

0 голосов
/ 29 июня 2019

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...