Что делает следующий код на C / C++?
if (blah(), 5) {
//do something
}
@ jfm3 не для меня домашнее задание, но кто-то в IRC-канале задал вопрос, и я подумал, что это хороший вопрос @Mark спасибо, я отметил язык в вопросе
«C / C++» - это не язык. Большинство респондентов, похоже, сосредоточены на перегрузке оператора запятой, поэтому C++. Вопрос, возможно, следует пометить заново.





Применяется оператор запятой, и значение 5 используется для определения истинности / ложности условного выражения.
Он выполнит blah () и получит что-то обратно (предположительно), затем будет использован оператор запятой, и 5 будет единственным, что будет использоваться для определения истинного / ложного значения для выражения.
Обратите внимание, что оператор, может быть перегружен для типа возвращаемого значения функции blah () (который не был указан), что сделает результат неочевидным.
Интересно (по крайней мере, для меня) то, что порядок операций, очевидно, не обеспечивается, когда вы перегружаете оператор запятой. В общем, я не думаю, что когда-нибудь сделаю это.
Напоминает мне об ошибке, которую я написал пару дней назад: хотел написать CAnObject a (d, f); но закончил писать CAnObject a = (d, f); К сожалению, произошло преобразование типа f в CAnObject. Ах.
Я бы сказал, что это зависит от blah ().
blah () будет вызываться, и мы не знаем побочных эффектов. Итак, отвечая на вопрос "что будет делать этот код?" это невозможно.
Я согласен с тобой, Бен. Недостаточно информации, чтобы сказать наверняка.
например, исключения. Или, если вы предпочитаете c, goto.
Если оператор запятой не перегружен, код выглядит следующим образом:
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++ есть оператор, который необходимо учитывать здесь
Ага - забыл, что в C++ можно переопределить оператор запятой. Думаю, в этом суть вопроса!
Следующее было написано в предположении, что это код C, либо в файле C, либо в блоке C файла C++:
Это бессмысленный если. Он вызовет blah (), однако результат blah () вообще не рассматривается если. Единственное, что учитывается, - это 5, поэтому if всегда будет иметь значение true. IOW вы можете написать этот код как
blah();
// do something
без всякого если вообще.
Да, к сожалению, кто-то мог заставить blah () вернуть объект, класс которого перегрузил оператор запятой, и тогда кто точно знает, что произойдет. Оператор запятой может сравнить что-то с 5 и вернуть false, полностью пропуская код в скобках.
Если это вообще C++ (даже в проекте C++ может быть простой файл C среди списка файлов); есть тег C++, но также тег C, и он также может находиться внутри блока extern «C», и в этом случае перегрузка невозможна.
В патологическом случае это зависит от того, что делает оператор запятой ...
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. Очевидно, что он никогда не должен появляться в производственном коде.
Следует указать язык в вопросе; Я не думаю, что тегов было бы достаточно, даже если бы здесь не было тегов C и C++.