Страницы

Поиск по вопросам

четверг, 18 октября 2018 г.

непонятное поведение аргумента функции

когда вызываю функцию прямо в ostream, не получаю нужный результат, а когда вызываю до cout, то все нормально...
#include #include using std::string;
string pop_word(const char*& p) { const char* q = p; size_t count = strlen(q); string s = p; while (!isdigit(*q) && --count > 0) ++q; string str = s.substr(0, q - p); while (*q == ' ' && --count > 0) ++q; if (*q) p = q; return str; }
int main() { const char* p = "unsigned 45678"; const char* q = p;
string s = pop_word(p); std::cout << s << '
' << p << '
'; // p указывает на "45678" (все нормально)
std::cout <' << q; //почему q указывает на "unsigned 45678"? return 0; }
Заранее извените за плохо изложенный вопрос, и спасибо за внимание и ответ


Ответ

Наблюдаемое вами поведение вызвано тем, что ваш компилятор не удовлетворяет требованиям С++17 или работает в до-C++17 режиме.
До С++17 порядок вычисления аргументов в выражении
std::cout << pop_word(q) << '
' << q;
был не специфицирован. Компилятор имел право сначала вычислить (подготовить, передать) аргумент q, а затем вычислить аргумент pop_word(q). А мог поступить и наоборот. Так как pop_word(q) изменяет значение q, результат отличался бы в этих случаях.
Но начиная с С++17 левый операнд <<, как для встроенного, так и для перегруженного оператора, должен вычисляться до того, как вычисляется правый (спасибо @wololo за подсказку). Это означает, что в данном выражении вывод однозначен
unsigned 45678
P.S. Что интересно, GCC в режиме -std=c++17 -Wsequence-point все равно продолжает предупреждать о неопределенном поведении в
int i = 0; std::cout << ++i << ++i << ++i << std::endl;
хотя в С++17 никакого неопределенного поведения тут не должно быть.

Комментариев нет:

Отправить комментарий