- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
int main()
{
int i = 0;
goto A;
for (;i<3; ++i)
L:{
{
int x;
x += i;
if (0) { A: x = 0; goto B; }
printf("X: %d ",x);
}
{
int y;
y -= i;
if (0) { B: y = 10; goto L; }
printf("Y: %d\n",y);
}
}
}
ну или как-то так.
А прыжок в точку, находящуюся после инициализации переменной, но в её зоне видимости, разве разрешается? Кресты вот запрещают.
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A pro-
gram that jumps77) from a point where a local variable with automatic storage duration is not in scope to a
point where it is in scope is ill-formed unless the variable has POD type (3.9) and is declared without an
initializer (8.5)
Получается, что впрыгнуть в блок можно даже в крестах, но только тогда, когда мы не пропускаем инициализацию переменных. Т.е. в данном случае все ок.
в с++03 пункт слово в слово
в с++11 дополнили:
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A
program that jumps from a point where a variable with automatic storage duration is not in scope to a
point where it is in scope is ill-formed unless the variable has scalar type, class type with a trivial default
constructor and a trivial destructor, a cv-qualified version of one of these types, or an array of one of the
preceding types and is declared without an initializer
Это только в свиче парит, приходится лишние фигрные скобочки ставить, потому что логика свича идиотская, и она же перешла блин во все жабошарпы.
switch, имхо, неудачная конструкция. Паскалевский case удобнее.
> Метки веток сами работают как границы блока.
Именно. И у каждой ветки свой скоп, независимый от других.
А, ещё если в метках упомянуты не все значения перечислимого типа, то ветка default (называется others правда) обязательна.
Ну на это, слава богу, и gcc ругаться умеет (опция -Wswitch, входит в -Wall). Спорно конечно, но имхо лучше ошибка/ворнинг, чем забытая ветка в свиче, когда я добавлю новое значение в enum.
Правда это не спасает, если есть заглушка
when others => null
(default : {} то бишь)
Если я хочу обработать вот это, вот это и вот это, а для всех остальных значений, включая будущие ничего не делать - я вставлю заглушку в default.
Если же нужно обработать вот это, вот это и вот это, при остальных имеющихся значениях ничего не делать, а что делать с будущими - хбз, то я вместо заглушки с default напишу пустышки с каждым из оставшихся вариантов. И тогда компилятор предупредит меня, если я добавлю новое значение в енум, но забуду внести его в свитч...
> предупреждение одного компилятора
Ну мне кажется все вменяемые компиляторы с\с++ его умеют выдавать.
А я же, между прочим, не зря писал про вменяемые компиляторы...
Под инициализацией там понимается именно int x = 2; а не int x; x = 2; Во втором случае все ок.
P.S. Ну да, на русский я очень вольно перевел, сорри.
Нет. Чтобы все охуели - нужен хаскель.
Кто меньше?
другое дело jmp far - c ним учишься прыгать далеко.
То ли дело j(x)!
ja, jna, jae, jnae, jb, jbe, jnb, jnbe, jo, jno, jz, je, jnz, jne, jc, jnc, jp, jnp, jg, jl, jge, jle, jng, jnge, jle, jnle.
И это я ещё половину забыл.
>nae b
Чую, что-то тут нечисто)