Статическое unsigned int foo и позже if (foo> 0)? - PullRequest
0 голосов
/ 16 сентября 2011

В книге сказано, что написание:

static unsigned int foo;

и позже

if( foo > 0)
{

не так, и это приведет к трудно найти ошибку. Почему это так?

В программировании на ассемблере x86 имеются подписанные арифметические инструкции и также без знака арифметические инструкции, JG JL <-подписанная арифметика JB JA <- неподписанные инструкции. </p>

Таким образом, компилятор может просто собрать оператор if (foo> 0) с неподписанными инструкциями не так ли? Может кто-нибудь объяснить, как это работает заранее?

Это инструкция неверна? Или, если есть разница в «C», где «C ++» строго в тот случай? Пожалуйста, объясните.

Здесь мы сравниваем переменную без знака с непосредственным значением. Что происходит внутри на самом деле компилятор в этом случае?

А когда мы сравниваем значение со знаком со значением без знака, что происходит? Тогда какие инструкции выберет компилятор, подписанные или неподписанные инструкции?

- заранее спасибо -

1 Ответ

2 голосов
/ 16 сентября 2011

На этот вопрос не следует отвечать на уровне ассемблера, а на уровне языка Си / Си ++. На большинстве архитектур невозможно сравнить числа со знаком и без знака, и c / c ++ не облегчает такое сравнение. Вместо этого существуют правила преобразования одного из операндов в тип другого для их сравнения - см., Например, ответы на этот вопрос

По сравнению с литералами - типичный способ сделать это (как вы сделали) не так уж и плох, но вы можете сделать это лучше - согласно стандарту c ++:

2.13.1.1 Целочисленный литерал - это последовательность цифр без точки или экспонентная часть. Целочисленный литерал может иметь префикс, который указывает его база и суффикс, который определяет его тип. Лексически первый цифра последовательности цифр является наиболее значимой. Десятичный целочисленный литерал (основание десять) начинается с цифры, отличной от 0, и списки последовательности десятичных цифр. Восьмеричное целое буквальное (базовое восьмой) начинается с цифры 0 и состоит из восьмеричной последовательности цифры 22) Шестнадцатеричный целочисленный литерал (основание шестнадцать) начинается с 0x или 0X и состоит из последовательности шестнадцатеричных цифр, которые включают десятичные цифры и буквы от A до F и от A до F с десятичные значения от десяти до пятнадцати. [Пример: число двенадцать может быть написано 12, 014 или 0XC. ]

2.13.1.2 Тип целочисленного литерала зависит от его формы, значения, и суффикс. Если он десятичный и не имеет суффикса, он имеет первый из эти типы, в которых может быть представлено его значение: int, long int; если значение не может быть представлено как long int, поведение не определено. Если он является восьмеричным или шестнадцатеричным и не имеет суффикса, он имеет первый из этих типов, в котором его значение может быть представлено: int, unsigned int, long int, unsigned long int. Если это суффикс U или U, его тип является первым из этих типов, в котором его значение может быть представлены: unsigned int, unsigned long int. Если это суффикс л или L, его тип является первым из этих типов, в которых его значение может быть представлены: long int, unsigned long int. Если это суффикс ul, lu, uL, Lu, Ul, lU, UL или LU, его тип без знака long int.

Если вы хотите быть уверены в своем литеральном типе (и, следовательно, типе comaprison), добавьте описанные суффиксы, чтобы обеспечить правильный тип литерала.

Стоит также отметить, что буквальное значение 0 на самом деле не десятичное, а восьмеричное - оно, похоже, ничего не меняет, но совершенно неожиданно - или я ошибаюсь?

Подводя итог - нельзя писать код подобным образом, но вы должны помнить, что в определенных условиях он может вести себя не интуитивно (или, по крайней мере, не математически;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...