Страницы

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

четверг, 12 декабря 2019 г.

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

#cpp


когда вызываю функцию прямо в 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  << '\n' << p << '\n';
    // p указывает на "45678" (все нормально)

    std::cout <


Ответы

Ответ 1



Наблюдаемое вами поведение вызвано тем, что ваш компилятор не удовлетворяет требованиям С++17 или работает в до-C++17 режиме. До С++17 порядок вычисления аргументов в выражении std::cout << pop_word(q) << '\n' << 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 никакого неопределенного поведения тут не должно быть.

Ответ 2



В каком порядке будут вычислены операнды неизвестно. В Вашем случае, сначала запоминается значение q, и только потом выполняется pop_word. Выведите q в следующем statement'е, думаю, там всё нормально. std::cout <

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

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