Что делает оператор запятой?

Что делает следующий код на C / C++?

if (blah(), 5) {
    //do something
}

Следует указать язык в вопросе; Я не думаю, что тегов было бы достаточно, даже если бы здесь не было тегов C и C++.

Mark Baker 30.09.2008 18:27

@ jfm3 не для меня домашнее задание, но кто-то в IRC-канале задал вопрос, и я подумал, что это хороший вопрос @Mark спасибо, я отметил язык в вопросе

Matt 30.09.2008 18:31

«C / C++» - это не язык. Большинство респондентов, похоже, сосредоточены на перегрузке оператора запятой, поэтому C++. Вопрос, возможно, следует пометить заново.

unwind 11.03.2009 23:45
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
40
3
2 557
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Ответ принят как подходящий

Применяется оператор запятой, и значение 5 используется для определения истинности / ложности условного выражения.

Он выполнит blah () и получит что-то обратно (предположительно), затем будет использован оператор запятой, и 5 будет единственным, что будет использоваться для определения истинного / ложного значения для выражения.


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

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

itsmatt 29.09.2008 20:45

Напоминает мне об ошибке, которую я написал пару дней назад: хотел написать CAnObject a (d, f); но закончил писать CAnObject a = (d, f); К сожалению, произошло преобразование типа f в CAnObject. Ах.

QBziZ 29.09.2008 22:11

Я бы сказал, что это зависит от blah ().

blah () будет вызываться, и мы не знаем побочных эффектов. Итак, отвечая на вопрос "что будет делать этот код?" это невозможно.

Ben Hoffstein 29.09.2008 20:54

Я согласен с тобой, Бен. Недостаточно информации, чтобы сказать наверняка.

itsmatt 29.09.2008 21:15

например, исключения. Или, если вы предпочитаете c, goto.

tfinniga 29.09.2008 22:43

Если оператор запятой не перегружен, код выглядит следующим образом:

blah();
if (5) {
  // do something
}

Если оператор запятой перегружен, результат будет основан на этой функции.

#include <iostream>
#include <string>

using namespace std;

string blah()
{
    return "blah";
}

bool operator,(const string& key, const int& val) {
    return false;
}

int main (int argc, char * const argv[]) {

    if (blah(), 5) {
        cout << "if block";
    } else {
        cout << "else block";
    }

    return 0;
}

(отредактировано, чтобы показать сценарий перегрузки оператора запятой. Спасибо Дэвиду Пьеру за комментарий)

Нет, в C++ есть оператор, который необходимо учитывать здесь

David Pierre 29.09.2008 20:38

Ага - забыл, что в C++ можно переопределить оператор запятой. Думаю, в этом суть вопроса!

jop 29.09.2008 20:45

Следующее было написано в предположении, что это код C, либо в файле C, либо в блоке C файла C++:

Это бессмысленный если. Он вызовет blah (), однако результат blah () вообще не рассматривается если. Единственное, что учитывается, - это 5, поэтому if всегда будет иметь значение true. IOW вы можете написать этот код как

blah();
// do something

без всякого если вообще.

Да, к сожалению, кто-то мог заставить blah () вернуть объект, класс которого перегрузил оператор запятой, и тогда кто точно знает, что произойдет. Оператор запятой может сравнить что-то с 5 и вернуть false, полностью пропуская код в скобках.

itsmatt 29.09.2008 21:18

Если это вообще C++ (даже в проекте C++ может быть простой файл C среди списка файлов); есть тег C++, но также тег C, и он также может находиться внутри блока extern «C», и в этом случае перегрузка невозможна.

Mecki 30.09.2008 15:11

В патологическом случае это зависит от того, что делает оператор запятой ...

class PlaceHolder
{
};

PlaceHolder Blah() { return PlaceHolder(); }

bool operator,(PlaceHolder, int) { return false; }

if (Blah(), 5)
{
    cout << "This will never run.";
}

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

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

Итак, если у вас есть (foo (), bar ()), обе функции будут выполнены, но значение выражения оценивается как bar () (а также тип выражения).

Хотя я не скажу, что для этого есть справедливое использование, обычно считается, что код немного труден для чтения. В основном потому, что не во многих языках используются такие конструкции. Итак, как личное практическое правило, я избегаю этого, если я не добавляю код в уже существующее выражение и не хочу полностью менять его формат.

Пример: у меня есть макрос (я не обсуждаю, следует ли вам использовать макросы или нет, иногда это даже не вы написали)

НАЙТИ ЧТО-ТО (X) (x> 2)? find_fruits (x): find_houses (x)

И я обычно использую его в таких заданиях, как my_possession = FIND_SOMETHING (34);

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

НАЙТИ ЧТО-ТО (X) (x> 2)? (LOG («ищем фрукты»), find_fruits (x)) :( LOG («ищем дома»), find_houses (x))

Иногда я использую подобные конструкции для отладки. Когда я заставляю if быть близким к истинному, независимо от возвращаемого значения blah. Очевидно, что он никогда не должен появляться в производственном коде.

Другие вопросы по теме