2016-01-04 2 views
2

В LP64 размер long и размер long long одинаковы (Apple Docs, Unix Docs).Лучше использовать длинный или длинный длинный в 64 бит

Есть ли какая-то разница, ограничивая себя пониманием того, что вы работаете на LP64-системе (как XCode появляется при компиляции для 64-битного), между long и long long? Есть ли причина в использовании для использования long вместо long long, если ваша цель - 64-битный интеграл?

Вот почему я спрашиваю. В Objective C на Xcode формат NSString (например, printf) и NSNumber используют типы данных, такие как int, long, long long и их неподписанные варианты при преобразовании чисел и текстовых и нестандартных номеров бит, таких как int16_t, int32. и int64_t. Это затруднит программирование вещей, требующих определенного минимального размера (т. Е. Сетевых или валютных приложений) или времени, когда вы хотите хранить данные определенного размера в NSNumber без приведения типов.

Безопасно, ограничив к любому устройству Intel Mac OS или IOS, чтобы использовать int для int32_t и long long для int64_t при взаимодействии с такими вещами как NSString-х функций форматирования и NSNumber?

ответ

2

Безопасно, ограничив к любому устройству Intel Mac OS или IOS, чтобы использовать Int для int32_t и долго долго int64_t при взаимодействии с такими вещами как NSString-х функций форматирования и NSNumber?

В соответствии с ILP32 & Соглашениями LP64 да, но вы должны действительно документировать, что вы полагаетесь на эти размеры.

Один из способов сделать это, чтобы использовать умный макрос, который возник (как я понимаю) в Linux ядре:

#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) 

Этот макрос будет генерировать ошибку во время компиляции, если его состояние аргумент верно, как в этом случае он пытается определить размер массива отрицательного размера. Вы можете использовать его в следующей простой функции:

static __attribute__((unused)) void _compile_time_use_only_() 
{ 
    BUILD_BUG_ON((sizeof(int) != 4)); 
    BUILD_BUG_ON((sizeof(long long) != 8)); 
} 

добавить, что ваш код, и если вы пытаетесь скомпилировать на любой системе, где int не 32 бита или long long не 64 бита, то вы получите ошибка времени компиляции. Во время исполнения практически нулевая стоимость (всего несколько байтов для неиспользуемой функции).

Обязательно прокомментируйте функцию, указав, что она делает!

Вы можете, конечно, утверждать размер других типов одинаково.

HTH

+0

Я собираюсь отметить это как правильно, потому что он ответил хотя бы на часть вопроса. Было бы неплохо узнать, есть ли разница между int и long в 32-битной системе или длинной и длинной в 64-битной системе. Чтобы добавить ответ, вы могли бы, конечно, поместить это в '#ifndef NDEBUG', чтобы он не получал никаких ресурсов при компиляции для выпуска. – Erroneous

+0

@Erroneous - под ILP32 'int' и' long' являются 32-битными целыми числами, между ними нет практической разницы, точно такой же код будет скомпилирован для двух типов, они фактически являются просто псевдонимами друг друга. Аналогично для любых других целочисленных типов, которые имеют одинаковый размер. HTH – CRD

+0

Почему вы выполняете двойную '()' -верку ваших проверок, когда сам макрос 'BUILD_BUG_ON()' '()' -wraps условие _ (такой, что он препроцессор в '... ((sizeof (int) ! = 4)) ... ') _? Есть ли особая причина для этого? Или это просто плохая привычка, которую вы выбрали из использования макросов, которые плохо написаны и не '()' -wrap их аргументы? –

0

Используйте либо NSInteger, либо int64_t. NSInteger = самый быстрый тип с не менее 32 бит и совместим с размерами массивов и т. Д. Int64_t = ровно 64 бит. Это также облегчит переход на Swift.

+1

'NSInteger' не« самый быстрый тип с по меньшей мере 32 битами ». Это [просто определено] (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Cocoa64BitGuide/64BitChangesCocoa/64BitChangesCocoa.html # // apple_ref/doc/uid/TP40004247-CH4-SW11) как эквивалент 'long' в 64-битных и' int' в 32-битных. –

+0

@KenThomases Но на большинстве архитектур быстрее 32-битный int и 64-битный int - это тот, который соответствует размеру регистра процессора ... который 32-битный на 32-битном и 64-битном в 64-битном. _ У вас есть какая-либо документация, в которой указывается, что 'NSInteger' ** не был выбран ** для этих размеров из-за размера регистра? _ Нет сомнений в том, что ряд решений был включен в решения, стоящие за этой функциональностью, аргумент, вероятно, что размер регистра был одним из этих соображений. –

+0

@Slipp: В верхней части документа, который я связал, есть причины: «требуется для 64-разрядной адресации», «согласованность, легкость портирования и« соответствие импеданса »». [Здесь] (https://developer.apple.com/library/content/documentation/Darwin/Conceptual/64bitPorting/HighLevelAPIs/HighLevelAPIs.html#//apple_ref/doc/uid/TP40001064-CH224-SW1), больше причин: будущее расширение, размер указателя, поддержка большого набора данных. Никогда не упоминайте размер регистра. 'NSInteger' должен был оставаться' int' для 32-битных приложений для двоичной совместимости. Для 64-битной, мотивации была не производительность, а скорость. –

Смежные вопросы