2012-02-26 3 views
1

Я только что прочитал отличный пост, Portable Fixed-Width Integers in C, все имеет смысл до почти конца, я задаюсь вопросом, что делает следующий пункт означает:данные кегль - интересно о хорошей должности

Конечно, если вы не имеют компилятора, совместимого с C99, но вам все равно придется писать свой собственный набор typedefs, используя специфические для компилятора знания ширины char, short и long primitive. Я рекомендую поместить эти typedef в заголовочный файл вашего собственного дизайна и добавить анонимное объявление объединения, показанное в листинге 2, в связанный исходный модуль, чтобы проверить их размеры; то есть мягко «напомнить», кому когда-нибудь может понадобиться портировать ваш код.

static union 
{ 
    char int8_t_incorrect[sizeof( int8_t) == 1]; 
    char uint8_t_incorrect[sizeof(uint8_t) == 1]; 
    char int16_t_incorrect[sizeof(int16_t) == 2]; 
    char uint16_t_incorrect[sizeof(uint16_t) == 2]; 
    char int32_t_incorrect[sizeof(int32_t) == 4]; 
    char uint32_t_incorrect[sizeof(uint32_t) == 4]; 
}; 

Листинг 2. Это анонимное объединение позволяет компилятору обнаруживать и сообщать ЬурейиЕ ошибки

Я экспериментировал небольшую программу:

typedef unsigned char int8_t; 
typedef unsigned short int16_t; 

union u { 
    char int8_incorrect[sizeof(int8_t)==1]; 
    char int16_incorrect[sizeof(int16_t)==2]; 
}; 


int main() { 
    return 0; 
} 

Там не проблема происходит через компилятор. Я изменил int8_t на следующее:

typedef unsigned int int8_t; 

Нет проблем.

В основном я пропустил то, почему этот примерный код может обнаружить ошибку.

Не могли бы вы уточнить, что я пропустил?

+0

Вы компилировались с полной отчетностью об ошибках? –

+0

Btw., Предполагая, что, например, 'sizeof (int16_t) == 2' не переносится. В некоторых встроенных системах 'sizeof (int16_t) == 1'. –

+0

Я думаю, что его нужно настроить, чтобы размеры превратились в число меньше нуля. Возможно, что-то более похожее: '[1 - 2 * (sizeof (xxx) == yyy)]' –

ответ

1

Если вы компилируете с gcc добавить -std=c89 -pedantic или -std=c99 pedantic к вашим gcc опции компиляции, чтобы получить предупреждение с этим ЬурейиМ и типом союза:

typedef unsigned int int8_t; 

Для этого ЬурейеГо:

typedef unsigned char int8_t; 

оно обычно вы не получаете никаких предупреждений, так как трюк заключается в проверке размера типа, а не на том, что это подписанный или неподписанный тип.

+0

То есть. После использования -std = 89 и -pedantic я получаю предупреждение: предупреждение: ISO C запрещает массив нулевого размера 'int8_incorrect' –

0

Я понимаю, что массивы длины 0 запрещены стандартом C. Если вы напишете sizeof(int8_t) == 1 как длину массива, а sizeof(int8_t) будет не 1, сравнение будет оцениваться до 0, и у вас будет незаконный размер массива.

Однако, по следующей ссылке показывает, что GCC делает позволяет нулевой длины массива:

http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

... так что если вы используете GCC, которые могут быть причиной, вы не получите ошибка.

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