Оператор запятой в С++ не оценивает второе выражение

Я написал следующий код:

#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)

Ответы

Ответ 1

int m = f(),v(); 

Этот оператор выполняет f() и присваивает возвращаемое значение m, затем объявляет функцию v(), которая возвращает тип int. int v();, также известный как наиболее неприятный синтаксический анализ.

Чтобы выполнить тест comma operator, попробуйте:

int m;
m = f(),v();
cout << m << endl;

см. образ жизни.

Ответ 2

Следующая вариация вашего кода демонстрирует, что это делает:

http://ideone.com/GBae0p

#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.

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

Потому что это обычно путает опыт и новых программистов, так как он вводится С++, позволяя вам помещать прототипы функций в тела функций, это называется наиболее неприятным синтаксический анализ.