g++ не принимает конструкцию вида #if MACROS

 
0
 
C++
ava
trupca | 01.10.2013, 19:51
использую такой код для определения порядка байтов на платформе под которой компилируется код (взял отседова).


#define CURRENT_BYTE_ORDER       (*(int *)"\x01\x02\x03\x04")
#define LITTLE_ENDIAN_BYTE_ORDER 0x04030201
#define BIG_ENDIAN_BYTE_ORDER    0x01020304

#define IS_LITTLE_ENDIAN (CURRENT_BYTE_ORDER == LITTLE_ENDIAN_BYTE_ORDER)
#define IS_BIG_ENDIAN    (CURRENT_BYTE_ORDER == BIG_ENDIAN_BYTE_ORDER)


к этому хочется добавить ещё и такую проверку:

#if (IS_LITTLE_ENDIAN == 0) && (IS_BIG_ENDIAN == 0)
#error NOT SUPPORTED ENDIAN
#endif


но g++ говорит - "нельзя" - и показыват фигу ошибку:

tmp.cpp:25:6: ошибка: оператор «*» не имеет левого операнда


видим он прав, но я не понимаю почему нельзя сделать вот например так:

#if IS_BIG_ENDIAN
cout << "hello world" << endl;
#endif


когда можно написать так:

#if 1
cout << "hello world" << endl;
#endif


как тогда договриться с компилятором что бы он понял, что нельзя компилировать код, когда ни одна из этих переменных не установлена в истину?
Comments (4)
ava
feodorv | 01.10.2013, 19:23 #
Цитата (trupca @  1.10.2013,  19:51 findReferencedText)
взял отседова

Ну там совсем другое дело, без дефайнов.


Цитата (trupca @  1.10.2013,  19:51 findReferencedText)
но я не понимаю почему нельзя сделать вот например так

Препроцессор таких наворотов не понимает. Самый грамотный путь, КМК, сгенерировать внешний хедер-файл самописной программой в Вашем стиле:
unsigned int v = *(unsigned int *) "\x01\x02\x03\x04";
printf( "#ifndef MY_HEADER_H\n" );
printf( "#define IS_LITTLE_ENDIAN %d\n", (v == 0x04030201u) ? 1 : 0);
printf( "#define IS_BIG_ENDIAN %d\n", (v == 0x01020304u) ? 1 : 0);
printf( "#endif\n" );

и уже его включать в Ваш код по анализу порядка следования байт. Проблемы могут быть с 64-битной платформой, а также всегда нужно будет следить при переносе кода на другую платформу, чтобы этот .h-файл был вытерт.


Вообще же, есть полезный инструмент autoconf, которым и стоит воспользоваться, на мой взгляд...
ava
trupca | 01.10.2013, 20:59 #
жаль, но то что вы предлагаете я использовать не могу - единственный возможный для меня вариант использовать препоцессор и вот по каким соображениям:
сами по себе танцы с препроцессором нужны для условной компиляции. это уже нужно для сериализация данных после обработки на big endian для последующей их обработки на le. причём есть условие: нельзя что бы из-за сериализации на big endian страдал код на litlle endian, а разделять код на две ветки нельзя, так как это может повлечь за собой трудно уловимые ошибки и снизить мобильность кода.
ava
xvr | 02.10.2013, 16:00 #
Цитата (trupca @  1.10.2013,  20:59 findReferencedText)
единственный возможный для меня вариант использовать препоцессор 

Это невозможно. Препроцессор не исполняет никакого кода, и он никак не связан с платформой, на которой работает. Он занимается исключительно обработкой текста программы. Никакие обращения из него к реалиям аппаратной платформы невозможны по определению  smile 
ava
trupca | 02.10.2013, 18:02 #
увы, да. и "хитрого" способа заставить то, что я хотел заставить работать, не существует. я не нашёл по крайней мере. мб кому то больше улыбнётся удача.
как я понял, просомтрев все доступные мне реализации определения текущей платформы с помощью препроцессора, существует лишь один способ её определения - просмотреть определены ли все известные дефайны всех известных (нужных) программисту компиляторов, сред и ОС на наличие дефайна по которому можно сделать вывод о том какая последовательность байт применяется на платформе. как, например, это сделано в бусте:

#elif defined(__i386__) || defined(__alpha__) \
   || defined(__ia64) || defined(__ia64__) \
   || defined(_M_IX86) || defined(_M_IA64) \
   || defined(_M_ALPHA) || defined(__amd64) \
   || defined(__amd64__) || defined(_M_AMD64) \
   || defined(__x86_64) || defined(__x86_64__) \
   || defined(_M_X64) || defined(__bfin__)

# define BOOST_LITTLE_ENDIAN
# define BOOST_BYTE_ORDER 1234
#else
# error The file boost/detail/endian.hpp needs to be set up for your CPU type.

который я и использовал. хорошо что он уже написан о_0
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
  xvr   trupca ava  feodorv
advanced
Submit