LINUX.ORG.RU

Условия для препроцессора

 ,


0

1

Добрый день!

Помогите, пожалуйста, с такой проблемой - есть у меня #define для одного значения-указателя размера:

#define MAXSIZE (1024) /* bytes */

...

//array declaration:
somearray[MAXSIZE];

В другом месте в коде есть такое место:

//data block
colourstable[256];

Я хочу сделать так:

//data block
colourstable[MAXSIZE / sizeof(Colour)];

Окей, работает. Точнее говоря я сделал вот-так, чтобы потом еще длину для циклов каждый раз не вычислять:

#define CTABLESIZE ((MAXSIZE) / sizeof(Colour))
...
colourstable[CTABLESIZE];

Теперь такой момент - эти colourstable и somearray сидят в одном union и somearray служит «выравнивателем» памяти, чтобы мне точно знать, сколько места занимает union. Не помню, как эта штуковина правильно называется - pad, padding, etc. Суть в том, что MAXSIZE может «гулять» в зависимости от версии (не так давно пришлось в два раза увеличить из-за другой структуры). Однако CTABLESIZE должен быть ровно 256. Ок, делаю так:

#define CTABLESIZE (UINT8_MAX + 1)
или
#define CTABLESIZE (1 << sizeof(char))
Кстати, дополнительный вопрос - какое написание более идеологически верное, если мне надо показать, что это количество различных значений одного канала цвета в ARGB-8888

Так вот, поставил я такой CTABLESIZE, а потом завтра провожу ревизию\рефакторинг\какойдругойбулщит и у меня появляется радостная возможность уменьшить MAXSIZE до 80 байт. Радостно пишу #define MAXSIZE 80 и офигеваю от того, что размер union'а по прежнему 1024 из-за того, что я из-за своего старческого маразма забыл, что у меня где-то в другом модуле описана CTABLESIZE.

Поэтому основной вопрос чего хочу - как мне на этапе компиляции громко и матерно ругаться, что MAXSIZE меньше CTABLESIZE. Компилятор gcc, pure C.

Заранее спасибо, надеюсь подробно и понятно описал проблему.

★★

Окей, работает. Точнее говоря я сделал вот-так, чтобы потом еще длину для циклов каждый раз не вычислять:

вычисления делаются препроцессором один раз

Поэтому основной вопрос чего хочу - как мне на этапе компиляции громко и матерно ругаться, что MAXSIZE меньше CTABLESIZE. Компилятор gcc, pure C.

#if MAXSIZE < CTABLESIZE
#error "Тут твои ругательства"
#endif
Harald ★★★★★
()
Ответ на: комментарий от Harald

вычисления делаются препроцессором один раз

Не, я про

//data block
colourstable[MAXSIZE / sizeof(Colour)];

int i;
for (i = 0; i < MAXSIZE / sizeof(Colour), i++)
...

#if MAXSIZE < CTABLESIZE #error «Тут твои ругательства» #endif

Спасибо, совсем забыл про эту директиву.

А по дополнительному вопросу свое мнение не выскажете?

sambist ★★
() автор топика
Ответ на: комментарий от sambist

for (i = 0; i < MAXSIZE / sizeof(Colour), i++)

любой минимально умеющий в оптимизацию компилятор сделает это один раз

и да, там точно запятая подразумевалась перед i++? %)

Harald ★★★★★
()
Ответ на: комментарий от Harald

любой минимально умеющий в оптимизацию компилятор сделает это один раз

Дык компилятор один раз, а мне эту хрень в каждом цикле писать. Потому и вынес)

Не, опечатался.

sambist ★★
() автор топика

#define -> const

anonymous
()

Кстати, дополнительный вопрос - какое написание более идеологически верное, если мне надо показать, что это количество различных значений одного канала цвета в ARGB-8888

Такое:

#define ARGB888_CHANNEL_MAX (UINT8_MAX + 1)
#define WHATEVER_IS_YOUR_CONSTANT ARGB888_CHANNEL_MAX

ilammy ★★★
()

какое написание более идеологически верное, если мне надо показать, что это количество различных значений одного канала цвета в ARGB-8888

Я бы так сделал:

// это количество различных значений одного канала цвета в ARGB-8888
#define CTABLESIZE (1 << 8)

Ну или явно 256, разницы в общем-то нет, так как все знают, что 1<<8 == 256. sizeof(char) только путаницу вносит в данном случае, имхо.

Kiborg ★★★
()
Ответ на: комментарий от ilammy

#define ARGB888_CHANNEL_MAX (UINT8_MAX + 1)

Ну и к чему эти извращения? Пиши "железно" 256 и не парься! Или на какой-нибудь архитектуре "внезапно" char станет 16-битным и придется выделять по 16кБ на поллитру?

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Ну, вот разве что только после поллитры uint8_t может стать 16-битным.

ilammy ★★★
()

sizeof(char) всегда вернет 1, потому что sizeof размер в char-ах и считает. Не в байтах или битах. Для размера char есть константы в limits, но вообще он почти везде соответствует 8 битам.

anonymous
()
Ответ на: комментарий от Eddy_Em

кстати, плохая практика пытаться угодить множеству различных архитектур сразу и не глядя. потому, что с вероятностью 99,99% на столь экзотичной архитектуре, где, например, чар равен 16, произвольно взятый сишный код даже не скомпилится, и причём, независимо от вот этого леса макросов.

next_time ★★★★★
()
Ответ на: комментарий от next_time

Из актуальных и популярных машин можно отметить многие архитектуры DSP от TI, например C54. если интересен полный список, можно просмотреть опмсания на каждую из архитектур, их не так много. Эти архитектуры не могут адресовать байты, только 16- или 32-битные слова. Поэтому CHAR_BITS там - 16, uint8_t не определен, а sizeof(uint16_t) = 2.

anonymous
()
Ответ на: комментарий от Harald

#if MAXSIZE < CTABLESIZE

в данном конкретном случае не взлетит, т.к

#define CTABLESIZE ((MAXSIZE) / sizeof(Colour))

а препроцессор ничего не знает про sizeof.

Тут нужен static assert в том или ином виде.

unterwulf
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.