Размер целочисленного литерала в VC ++ и GCC для 64-битных машин - PullRequest
2 голосов
/ 14 сентября 2011

Я пишу кроссплатформенный код x86 / x86-64 / Itanium, ориентированный на высокую производительность, и хотел бы избежать каких-либо ненужных операций, включая ненужное приведение типов.

Код, который у меня есть, вызывает такую ​​функцию, какthis:

int theResult = Function(anUInt, 10);

Очевидно, тип значения 10 не указан.И Function определяется следующим образом:

int Function (unsigned int anUInt, int anInt)
{
    // ...
}

Я предполагаю, что при использовании VC ++ и GCC для машин x86 размер целочисленного литерала составляет 4 байта, поэтому преобразование типов выполнять не нужно.при присвоении значения 10 параметру anInt при входе в указанную выше функцию (размер значения int равен 4 почти во всех моделях данных).Некоторые могут не считать это окончательным доказательством этого предположения, но sizeof(1) возвращает 4 в VC ++ и коде GCC, скомпилированном для архитектуры x86.И я предполагаю, что если бы размер целочисленного литерала на 64-битной машине был, скажем, 8 байтов, 8 байтов значения 10 пришлось бы преобразовать в 4 байта параметра anInt, что снизило бы производительность, если быFunction вызывается очень часто (как в моей программе).

Таким образом, размер целочисленного литерала будет равен 4 в VC ++, а код GCC скомпилирован для 64-битной архитектуры, например, x86-64или итаниум, или будет 8?Другими словами, что вернет sizeof(1) в коде VC ++ и GCC для 64-битных машин?Какие-нибудь особые случаи для архитектуры Itanium (IA-64)?

Редактировать: изменено "нетипизированное целое число" на "целочисленное литеральное".

Ответы [ 4 ]

5 голосов
/ 14 сентября 2011

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

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 или L, его тип является первым из этих типов, в которых может быть представлено его значение: long int, unsigned long int.Если к нему добавляются суффиксы ul, lu, uL, Lu, Ul, lU, UL или LU, его тип - unsigned long int.

1 голос
/ 13 декабря 2011

Кажется, вы делаете одну из классических ошибок: преждевременная оптимизация. Кстати, он был назван "корнем всего зла";) Если вы хотите написать быстрое приложение, напишите его, профилируйте (используя valgrind или что-то подобное), а затем оптимизируйте медленные части. Для начала используйте известную теорию структур данных и алгоритмы, но любые другие оптимизации оставляют за компилятором. Скажите ей, чтобы она встроила вашу функцию, если вы действительно уверены, что она нужна, но компилятор, вероятно, все равно сделает это.

Кроме того, вы, похоже, смущены тем, как работают целочисленные размеры. Вы компилируете программу для 32- или 64-битного размера, а затем вы можете запускать как 32-, так и 64-битные программы на 64-битной архитектуре. Во всех случаях int - это int. Если вы скомпилировали его для 32 битов, ваши целые будут 4 байта. Если вы скомпилировали его для 64 бит, они будут 8 байтов. В любом случае, во время выполнения не происходит повышения или понижения для целых литералов. При запуске 32-разрядной программы на 64-разрядном оборудовании может быть 8-байтовое хранилище целых 4-байтовых чисел, но это будет только то, как оборудование решит выполнить вашу программу и будет полностью невидимым для вашей программы и не заставит ее беги медленнее. Запуск 32-разрядных приложений на 64-разрядном оборудовании и ОС обычно влечет за собой штраф в несколько процентов, поэтому вы должны выпустить выделенную 64-разрядную сборку, если вам действительно нужна такая производительность.

Похоже, что ваш вопрос действительно может звучать так: «Сколько байтов является целым числом при компиляции для 64-битного оборудования», поскольку предположение, что оно может быть или не быть 8 байтов, заставляет вас беспокоиться о производительности проблемы. Кажется, ответ: int имеет длину 4 байта как на 32-битном GCC, так и на 64-битном GCC. Итак, ваша первоначальная забота спорная; размер такой же, и, следовательно, продвижение или понижение не потребуется.

1 голос
/ 14 сентября 2011

Тип целочисленного литерала (например, 10) по умолчанию равен int. *

То есть, 4 или 8 байтов, зависит от размера int на вашей платформе (я подозреваю, что это 4 для обеих платформ, о которых вы упомянули).

* См. Таблицу в разделе 2.14 стандарта C ++ (03);он описывает, как выбираются типы для целочисленных литералов.

0 голосов
/ 14 сентября 2011

Приведение типа целочисленного литерала произойдет во время компиляции, а не во время выполнения. Компилятор должен выбрать наиболее подходящие инструкции для загрузки значения, так как оно будет использоваться остальной частью выражения.

...