Подтвердить что ты не робот

Используется ли поведение undefined для кода asm?

Скажем, вы знаете, что ваше программное обеспечение будет работать только на двух компьютерах с дополнениями, где хорошо знакомы правила поведения с переполнением. Подписанным переполнением по-прежнему остается undefined поведение на C и С++, и компилятор может заменить всю вашу программу "ret", начать ядерную войну, форматировать ваш диск или заставить демонов вылететь из вашего носа.

Предположим, что вы подписали переполнение в inline asm, ваша программа все еще вызывает UB?

Если да, что относительно отдельно скомпилированного и связанного ассемблера?

4b9b3361

Ответ 1

"Undefined поведение" означает C resp. Стандарты С++ не определяют поведение вашей программы. Если ваша программа содержит встроенную сборку, должно быть довольно ясно, что ее поведение обычно не описывается ни C, ни стандартом С++. Некоторые другие стандарты могут даже определять поведение, но это все еще не означает "определенное поведение" в контексте стандарта C или С++.

Тем не менее, стандарт C требует документации поддерживаемых расширений. Если поведение вашей программы может быть выведено из вашей документации по внедрению, а ваша реализация ведет к тому, что ваша программа ведет себя по-другому, это означает, что ваша реализация соответствует стандарту:

4. Соответствие

8 Реализация должна сопровождаться документом, который определяет все специфичные для реализации и специфичные для локали характеристики и все расширения.

Для С++ это требование ослаблено:

1.4 Соответствие требованиям [intro.compliance]

9 Каждая реализация должна включать документацию, которая идентифицирует все условно поддерживаемые конструкции, которые она не поддерживает, и определяет все специфические для локали характеристики.

и

1.9 Выполнение программы [intro.execution]

2 Некоторые аспекты и операции абстрактной машины описаны в настоящем Международном стандарте в качестве реализации [...] Каждая реализация должна включать документацию, описывающую ее характеристики и поведение в этих отношениях. [...]

Я не могу найти требование для документирования и документирования расширений, которые должны быть задокументированы правильно. Это предполагает, что в С++, даже если ваша реализация определяет поведение вашей программы как расширения, если окажется, что документация неверна, это слишком плохо.

Для полустандартного С++-выражения asm (как указано в комментариях, "объявление asm условно поддерживается, его значение определяется реализацией." ), если ваша реализация поддерживает его, это должно быть но, конечно, общепринятой практикой для внедрений является поддержка встроенной сборки по-другому, чем намечено стандартом С++, поэтому это не дает вам много лишнего.

Ответ 2

Как только вы говорите, что подписали переполнение в inline asm, это означает, что вы говорите о компиляторе (или наборе компилятора), потому что в C, как и в С++, поддержка объявления asm и его смысл - это компилятор определены.

Если компилятор определяет ключевое слово asm, разрешив прямое включение кода сборки в свой вывод, и если машина разрешает переполнение подписей, то подписанное переполнение в inline asm отлично определено для этого компилятора и этой машины: это то, что процессор даст в результате. Вы все равно должны контролировать, может ли это привести к представлению ловушки для целого числа со знаком, но в любом случае оно определено. Единственный случай, который закончится в UB, будет заключаться в том, что компилятор говорит, что некоторое представление в значении integer вызовет поведение undefined. Но я ничего не знаю, и вы уже находитесь в контексте определенного и конечного набора компиляторов и машин.

Отдельная компиляция модуля сборки и кода C и/или С++ будет одинаковой для этого набора компиляторов и машин: результат реализованный вариант реализации, который не совпадает с UB.

Еще один пример того, что явно реализуется в стандартах (как C, так и С++), заключается в том, подписан ли тип char или нет: если вы не знаете, какой компилятор вы используете, вы не можете полагаться на него, но , как только вы выберете реализацию компилятора, эта реализация должна сказать, является ли она подписанной или неподписанной, и это поведение не undefined, что означает, что компилятор не может заменить полный код с ret, например.