LINUX.ORG.RU

[gcc][gnu с/c++] Баг?

 


0

1

Вопрос касается использования ({})-расширения.

for(int i=0;i<3;({break;}));
 -> error: break statement not within loop or switch

for(int i=0;i<3;i++)
 for(int j=0;j<3;({break;}))
  printf("%d - %d\n",i,j);
 -> 0 - 0
    1 - 0
    2 - 0

То есть в первом случае компилятор не дает использовать ({break;}) внутри «шапки» (не знаю, как правильно назвать) цикла, а во втором преспокойно обрывает цикл, в шапке которого он указан. Получается, на этапе обработки семантических ошибок он рассматривает брэйк внутри внешнего цикла, а на этапе трансляции перемещает его во внутренний.

Гцц-4.4.4, сейчас собираю 4.5.2. Раньше, емнип, такого безобразия я не наблюдал, и компилятор на обоих этапах вел себя будто брэйк относится к тому циклу, в шапке которого указан. Мне кажется это логичным: третья часть (step) шапки for-а должна выполняться после каждой итерации, таким образом вырубать цикл после первого прохода.

ПС. Изврашаться с языком приходится, чтобы соорудить макрос.

★★★★★

С 4.5.2 ничего не изменилось. Возможно раньше не замечал, потому что использование таких конструкций всегда попадало во вложенные циклы...

Таки это баг? Фича? Моя криворукость?

staseg ★★★★★
() автор топика
Ответ на: комментарий от trex6

>Во втором случае break у тебя относится к первому циклу.

Как тогда первый цикл выполнился все положенные три раза, а внутренний - по разу?

staseg ★★★★★
() автор топика
	for (int i = 0; i < 3; i++)
		for (int j = 0; j < 3; ({ break; }))
			printf("%d - %d\n", i, j);

Выводится, как и положено, «0 - 0». Верное поведение наблюдается как на версии 4.4.5, так и на версии 4.5.1.

twosev ★★
()
Ответ на: комментарий от twosev

А вот clang относит записанный таким образом break к циклу, в шапке которого тот находится.

twosev ★★
()
Ответ на: комментарий от twosev

Напрягал Иван глаза...

>Выводится, как и положено, «0 - 0».

А почему так положено? Мне кажется логичным другое поведение, ход мыслей я описал в сообщении.

Верное поведение наблюдается как на версии 4.4.5, так и на версии 4.5.1.

А описанное мною поведение наблюдалось на 4.4.4 и 4.5.2, i386 и на 4.5.2, amd64.

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

staseg ★★★★★
() автор топика
Ответ на: Напрягал Иван глаза... от staseg

> А почему так положено?
Потому что break должен находиться в теле цикла/свитча. В указанном выше примере он находится в теле внешнего цикла, но не внутреннего.

twosev ★★
()
Ответ на: комментарий от shty

> непереносимо же

Да, непереносимо дурной.

anonymous
()
Ответ на: комментарий от pylin

Потому, что нестандарт. А значит, не будет работать нигде, кроме данной конкретной версии компилятора. Подозреваю, в частности, что не будет работать в режиме C++0x. Не говоря уже о том, что не будет работать в других компиляторах. Нам стандарт для того и даден, чтобы мы могли писать универсальные кросс-платформенные приложения.

Vamp
()

>Изврашаться с языком приходится, чтобы соорудить макрос.

Больше никогда не делай таких макросов)

annulen ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.