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

В моей программе на C++ у меня есть эта функция,

char MostFrequentCharacter(ifstream &ifs, int &numOccurances);

и в main() этот код,

ifstream in("file.htm");
int maxOccurances = 0;
cout <<"Most freq char is "<<MostFrequentCharacter(in, maxOccurances)<<" : "<<maxOccurances;

Но это не работает, хотя я получаю правильный символ, maxOccurance остается нулевым. Но если я заменю приведенный выше код в основном с этим,

ifstream in("file.htm");
int maxOccurances = 0;
char maxFreq = MostFrequentCharacter(in, maxOccurances);
cout <<"Most freq char is "<<maxFreq<<" : "<<maxOccurances;

Тогда он работает правильно. Мой вопрос, почему это не работает в первом случае.

4 ответа

В C++

cout << a << b 

По ассоциативности оценивает:

(cout << a) << b 

но компилятор может свободно оценивать их в любом порядке.

т.е. компилятор может оценить b будет первый a тогда первый << операция и вторая << операция. Это потому, что нет точки последовательности, связанной с <<


Для простоты рассмотрим следующий код, который эквивалентен:

 #include<iostream>
    int main()
    {
       int i = 0;
       std::cout<<i<<i++;
       return 0;
    }

В приведенном выше исходном коде:

std::cout<<i<<i++;

оценивает вызов функции:

operator<<(operator<<(std::cout,i),i++);

В этой функции вызывать ли operator<<(std::cout,i) или же i++ оценивается первым - Unspecified. то есть:

operator<<(std::cout,i) может быть оценен первым или
i++ может быть оценен первым или
Некоторая Magic Ordering реализована компилятором

Учитывая вышеизложенное, нет способа определить это упорядочение и, следовательно, объяснение также невозможно.


Соответствующая цитата из стандарта C++03:
Раздел 1.9

Некоторые другие аспекты и операции абстрактной машины описаны в этом международном стандарте как неопределенные (например, порядок оценки аргументов функции). Там, где это возможно, этот международный стандарт определяет набор допустимого поведения. Они определяют недетерминированные аспекты абстрактной машины.

Поскольку в первом случае значение maxOccurances в выражении разрешается до вызова MostFrequentCharacter. Хотя это не должно быть так, это неопределенное поведение.

Вы можете получить разные результаты с разными компиляторами или опциями компилятора. Если вы попробуете то же самое на VC++, например, я думаю, вы увидите другие результаты.

Вы просто должны отметить, что там, где вы видите << вы на самом деле звоните operator<< метод - так что компилятор определяет значение аргументов для передачи в эту функцию до изменения вашей переменной.

Другими словами, то, что у вас есть, похоже на

operator<<(operator<<(cout, f(x)), x);

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

Cout работает справа налево в вашем компиляторе, поэтому сначала оценивается самый правый, а затем левый.:) Таким образом, значение указанной переменной не изменилось.

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