Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ С\С++ _ Нюанс оператора вывода в поток

Автор: Litkevich Yuriy 8.4.2010, 15:16

Тут для себя интересное открытие совершил. Был код:

int size = combo->count();
int index = 0;
qDebug() << "=== INDEX -" << index << "===";
while (index != size){
    qDebug() << "INDEX:" << index << "\tVALUE:" << combo->itemText(index++);
}
Ожидал, что будет напечатано:
=== INDEX - 0 ===
INDEX: 0        VALUE: "text-1"
INDEX: 1        VALUE: "text-2"
Однако напечатано было:
=== INDEX - 0 ===
INDEX: 1        VALUE: "text-1"
INDEX: 2        VALUE: "text-2"
Я полагал, что инкремент будет последней операцией, однако он почему-то стал второй. Т.е. получается выполнение идёт с конца оператора вывода в поток.
Код переделал так:
int size = combo->count();
int index = 0;
qDebug() << "=== INDEX -" << index << "===";
while (index != size){
    qDebug() << "INDEX:" << index << "\tVALUE:" << combo->itemText(index);
    index++;
}
тогда стало печататься как ожидаемо.

Может кому-то пригодится

Автор: Влад 8.4.2010, 21:30

Попробуй сам себе ответить на следующие вопросы: что есть выражение "qDebug() << нечто" в смысле языка C++ ? Где точки следования? В каком порядке будут вычисляться подвыражения этого полного выражения? Почему? В какой момент они должны быть вычислены? Почему?

Автор: Litkevich Yuriy 8.4.2010, 22:04

Цитата(Влад @ 9.4.2010, 1:30) *
что есть выражение "qDebug() << нечто" в смысле языка C++ ?
у меня была аналогия с оператором "+", т.е.
A + B + C
которая распадается на:
A + B = Результат1
и
Результат1 + C
но эта аналогия не работает для оператора "<<"

Автор: Tonal 12.4.2010, 10:43

Это один из видов классического UB.
Твой код эквивалентен следующему:

int a = 0;
int b = a + a++;
cout<<b;

Вывод может быть как 0 так и 2.

Да, код вывода я бы на for переделал. :)

Автор: Litkevich Yuriy 12.4.2010, 13:29

Цитата(Tonal @ 12.4.2010, 14:43) *
я бы на for переделал
я избегаю использовать for, т.к. его форма записи для меня не очевидна, нужно помнить, а не просто читать, каково его поведение. Т.е. выход по истинности или ложности. С while этой проблемы для меня нет. т.к. я просто читаю:
пока (что-то){
    делаем что-то
}

С паскалеподобным for у меня тоже нет проблем:
для i от 5 до 10 с шагом 1{
    делаем что-то
}

Автор: Tonal 15.4.2010, 10:17

Цитата(Litkevich Yuriy @ 12.4.2010, 17:29) *
я избегаю использовать for, т.к. его форма записи для меня не очевидна, нужно помнить, а не просто читать, каково его поведение.

Выход из циклов в С всегда по лжи - помнить нужно только это.
Базовые формы языка нужно знать, аднака. :)

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)