Я написал следующий код:
#include <iostream>
using namespace std;
int f()
{
cout << "f()" << endl;
return 3;
}
int v()
{
cout << "v()" << endl;
return 4;
}
int main()
{
int m = f(),v();
cout << m << endl;
return 0;
}
Я ожидал, что это напечатает:
f()
v()
3
составление с g++ -O0 test.cpp -o test.out
и текущие результаты:
f()
3
Почему вызов v опущен? (это нельзя сделать для оптимизации, потому что я добавил флаг -O0
)
int m = f(),v();
Этот оператор выполняет f () и присваивает возвращаемое значение m, затем объявляет функцию v()
которые возвращают тип int. int v();
также известен как самый неприятный разбор.
Чтобы достичь вашего comma operator
проверить, попробовать:
int m;
m = f(),v();
cout << m << endl;
увидеть живой образец.
Следующий вариант вашего кода демонстрирует, что он делает:
#include <iostream>
int f() { std::cout << "f()" << std::endl; return 1; }
int main() {
int t = f(), v();
std::cout << t << std::endl;
return 0;
}
Компилируется без ошибок, даже если у нас нет «v ()».
Оператор запятой разбивает эту строку
int t = f(), v();
в
int t = f();
int v();
Вторая строка — это прототип функции, который объявляет, что будет функция, int v()
, который не принимает параметров и возвращает int.
Он не вызывает его, он просто предварительно объявляет его — в случае, если компилятор встречает его вызов до того, как он будет определен на самом деле — потому что тело является пустым оператором (;
). Компилятор предполагает, что мы реализуем его позже или в другом модуле компиляции.
Поскольку это обычно сбивает с толку опыт и новых программистов, так как он введен в C ++ и позволяет помещать прототипы функций в тела функций, это называется самый неприятный разбор.