Предполагая, что вы просто хотите, чтобы это помогло вам определить размер различных типов в вашей целевой системе без необходимости фактически запускать программу в целевой системе, но вы не намерены использовать этот инструмент как интегрированный инструмент. в систему сборки, у меня может быть взлом для вас ...
Для взлома требуется запуск компилятора для компиляции программы, но вам не нужно нигде запускать скомпилированный вывод. На самом деле этот хак разработан, чтобы рассказать вам, что вы хотите знать, генерируя ошибки компилятора.
Небольшой макрос здесь заставит компилятор выдать сообщение об ошибке, соответствующее размеру данного типа. Он также выдаст сообщение об ошибке «конец поиска» на случай, если вы передадите ему тип, который больше, чем тот, который он проверяет. Это просто «удобство», чтобы напомнить вам, что нужно добавить еще несколько строк в макрос, чтобы он обрабатывал интересующий вас тип.
Некоторые из основных ограничений:
- это ужасно нахально
- она сообщает вам ужасную информацию
- он будет работать только с типами, которые могут быть выражены как одно слово (поэтому
typedef
необходим для таких вещей, как long double
, как показано в примере).
Но если вам когда-нибудь интересно узнать размер какого-либо типа и вы не хотите на самом деле запускать программу на цели для printf()
получения информации, это может помочь.
Вот макрос (ы) вместе с некоторыми примерами его использования:
#if !defined( PASTE)
#define PASTE2( x, y) x##y
#define PASTE( x, y) PASTE2( x, y)
#endif /* PASTE */
#define SAY_IF_SIZEOF( type, size) static char PASTE( PASTE( PASTE( sizeof_, type), _is_), size) [(sizeof(type) == (size)) ? -1 : 1]
#define SAY_SIZEOF_END(type) static char PASTE( end_search_for_sizeof_, type)[-1]
#define SAY_SIZEOF(type) \
SAY_IF_SIZEOF( type, 1); \
SAY_IF_SIZEOF( type, 2); \
SAY_IF_SIZEOF( type, 3); \
SAY_IF_SIZEOF( type, 4); \
SAY_IF_SIZEOF( type, 5); \
SAY_IF_SIZEOF( type, 6); \
SAY_IF_SIZEOF( type, 7); \
SAY_IF_SIZEOF( type, 8); \
SAY_IF_SIZEOF( type, 9); \
SAY_IF_SIZEOF( type, 10); \
SAY_IF_SIZEOF( type, 11); \
SAY_IF_SIZEOF( type, 12); \
SAY_IF_SIZEOF( type, 13); \
SAY_IF_SIZEOF( type, 14); \
SAY_IF_SIZEOF( type, 15); \
SAY_IF_SIZEOF( type, 16); \
SAY_SIZEOF_END(type)
//here's where you get to ask about the size of a type
SAY_SIZEOF(float);
typedef long double long_double;
SAY_SIZEOF(long_double);
struct foo {
char x;
short y;
int* p;
};
struct bar {
char x;
int* p;
short y;
};
typedef struct foo foo_t;
typedef struct bar bar_t;
SAY_SIZEOF(foo_t);
SAY_SIZEOF(bar_t);
int main(void)
{
return 0;
}
И вот что говорит компиляция этой программы с помощью GCC / MinGW 4.5.1:
C:\temp\test.c:34:1: error: size of array 'sizeof_float_is_4' is negative
C:\temp\test.c:34:1: error: size of array 'end_search_for_sizeof_float' is negative
C:\temp\test.c:38:1: error: size of array 'sizeof_long_double_is_12' is negative
C:\temp\test.c:38:1: error: size of array 'end_search_for_sizeof_long_double' is negative
C:\temp\test.c:56:1: error: size of array 'sizeof_foo_t_is_8' is negative
C:\temp\test.c:56:1: error: size of array 'end_search_for_sizeof_foo_t' is negative
C:\temp\test.c:57:1: error: size of array 'sizeof_bar_t_is_12' is negative
C:\temp\test.c:57:1: error: size of array 'end_search_for_sizeof_bar_t' is negative
Итак, вы можете легко увидеть, что:
float
- 4 байта
long double
составляет 12 байтов
struct foo
составляет 8 байтов
struct bar
- 12 байтов (отличается от struct foo
из-за различий выравнивания / заполнения)
Надеюсь, это поможет. На самом деле, были времена, когда я хотел бы этого ... Обычно, если мне интересно узнать размер структуры моих встроенных целей, я выискиваю эту информацию в отладчике или мне приходится взламывать отладку printf()
где-то.
Я думаю, что на самом деле это будет проще:
- интересно, насколько велик что-то
- сбросить
SAY_SIZEOF()
'call' в исходный файл
- нажмите Shift-Ctrl-B (или любую горячую клавишу для компиляции / сборки), получите информацию и
- удалить
SAY_SIZEOF()
'вызов'