2013-03-26 5 views
1

Почему следующая распечатка «World Hello!»?Очень странный приоритет/точность в функции C++

Из моего понимания, в соответствии с приоритетом оператора, это следует оценивать слева направо. Но вместо этого кажется, что это право налево вправо. Почему это?

#include <iostream> 

using namespace std; 


char print() { 
    cout << "World"; 
    return '!'; 
} 

int main() { 
    cout << "Hello " << print() << endl; 
    return 0; 
} 
+1

Извините, неверная ссылка. Должно быть [Порядок оценки операндов] (http://stackoverflow.com/questions/7112282/order-of-evaluation-of-operands?lq=1) –

+0

Прошу прощения, я все еще новичок в этом. Я не знал, что эта тема имеет отношение к моей проблеме. – xyz

+1

Ваше понимание неверно. Заказ не определен, т. Е. Он может быть слева направо, справа налево или с середины наружу зигзагами. –

ответ

6

Я не думаю, что стандарт дает никаких гарантий относительно точного момента, когда print() называется относительно применения << оператор.

В вашем случае это выглядит как print() называется первым, тогда оценивается cout << Hello, и только тогда оценивается [result of the previous expression] << [result of print()].

1

Заказ не определен. Посмотрите на Order of evaluation.

cout << i << i++; // Undefined behavior 
+1

Порядок оценки * не указан *, который технически немного отличается от * undefined *. А также отличается от вашего примера. –

2

это следует оценивать слева от правой.

Он делает. Вы можете видеть это с ! в самом конце. Но окончательная строка печатается coutпосле Операторы были оценены. Но, во время оценка оператора, вы печатаете World. Затем печатается Hello!. Следовательно, вы получаете WorldHello!.

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

@Bo дал очень хорошую ссылку, которая указывает на C++ стандарт:

§5.2.2.8 - [...] The order of evaluation of function arguments is unspecified. [...] 
4

Это становится

operator<< 
(
    operator<< 
    (
     cout, 
     "Hello" 
    ), 
    print() 
) 
.operator<< 
(
    endl 
); 

Порядок evalutation аргументов unspecified, так что нет ничего о том, что сокровенное operator<< должен быть оценен, прежде чем print() в вызове второго сокровенном operator<<.

Подумайте об этом следующим образом: foo(f1(), f2());. Что будет оцениваться первым, f1() или f2()? Мы не знаем. Мы знаем только, что оба будут завершены до foo().

Левый на правый precedence означает, что он заканчивается тем, как я его написал.

Много позже редактирование: Незначительная техническая ошибка. Вызов endl будет фактически версией участника. Не имеет никакого значения ни на что другое.

Смежные вопросы