Это связано с тем, что компилятор должен инициализировать во время выполнения кадр области действия с помощью VLA. Другими словами, вы говорите ему перейти к адресу :END
, но вы просите его перепрыгнуть через код инициализации фрейма этой области.
Код для инициализации пространства для VLA находится непосредственно перед выражением, вычисляющим длину VLA. Если вы пропустите этот код, что могут сделать некоторые goto, то вся программа выдаст ошибку.
Представьте что-то вроде:
if (cond) goto end;
...
char a[expr];
end:
a[i] = 20;
В этом случае код просто выдаст ошибку, так как вы перейдете к мутатору VLA a, но a не был инициализирован. Вместо определения должен быть вставлен код для инициализации VLA.
Теперь о alloca
. Компилятор сделает то же самое, но не сможет обнаружить segfault.
Так что это будет segfault без предупреждения/ошибки со стороны компилятора.
Логика та же, что и для VLA.
int main(int argc, char *argv[])
{
goto end;
char *s = alloca(100);
end:
s[1] = 2;
return 0;
}
Вот почему в ISO 9899 они вставили утверждение:
6.8.6.1 Оператор goto. Ограничения
1 Идентификатор в операторе goto должен называть метку, расположенную где-то во внешней функции. Оператор goto не должен переходить из-за пределов области действия идентификатора, имеющего изменяемый тип, внутрь области действия этого идентификатора.
Компилятор не может определить во время статического анализа правильный ответ для этой задачи, так как на самом деле это halting problem
.
person
alinsoar
schedule
02.06.2017
sizeof(char*)
исправлено. Я добавил тег юриста, чтобы увеличить шансы получить достойный ответ. - person Bathsheba   schedule 02.06.2017s
после перехода за пределыalloca
уже является UB, посколькуs
будет неинициализированным указателем, но использованиеs
после перехода за пределы объявления VLA было бы в порядке, если бы сам переход не был запрещен. - person Tor Klingberg   schedule 02.06.2017alloca
не входит в стандарт, поэтому компилятор может рассматривать ее как любую другую функцию (хотя они часто нет), и в этом случае по стандарту все в порядке. Хотя, конечно, это может привести к аналогичному неопределенному поведению - person Kninnug   schedule 02.06.2017alloca
не является стандартной функцией. Этот вопрос действительно касается контраста между VLA:s иalloca
. Вопрос только для VLA уже существует (здесь)[stackoverflow.com/questions/20654191/. - person Tor Klingberg   schedule 02.06.2017