Что означает ошибка компилятора "отсутствующий двоичный оператор перед маркером"?
Недавно я попытался скомпилировать gcc:
ошибка: отсутствующий двоичный оператор перед токеном "("
Поиски в Интернете и SO придумали несколько конкретных примеров этой ошибки, с конкретными изменениями кода, чтобы исправить их. Но я не нашел общего описания того, какое условие вызывает эту ошибку.
Когда и почему gcc испускает эту ошибку?
Ответы
Ответ 1
Это не ошибка компилятора, это ошибка препроцессора. Это происходит, когда препроцессор сталкивается с недопустимым синтаксисом при попытке оценить выражение в директиве #if
или #elif
.
Одной из общих причин является оператор sizeof
в директиве #if
:
Например:
#define NBITS (sizeof(TYPE)*8)
//later
#if (NBITS>16) //ERROR
Это ошибка, потому что sizeof
оценивается компилятором, а не препроцессором.
Тип приведения также недействителен синтаксисом препроцессора:
#define ALLBITS ((unsigned int) -1)
//later
#if (ALLBITS>0xFFFF) //ERROR
Здесь правила для допустимого выражения.
Обратите внимание, что #if
будет оценивать макрос undefined как 0, если только он не выглядит так, как будто он принимает аргументы, и в этом случае вы также получите эту ошибку:
Итак, если THIS
- undefined:
#if THIS == 0 //valid, true
#if THIS > 0 //valid, false
#if THIS() == 0 //invalid. ERROR
Опечатки в инструкции #if
также могут вызывать это сообщение.
Ответ 2
Если вы работаете в Linux, убедитесь, что в файлах вашего проекта нет заголовка с именем features.h
. У меня был один с этим именем, что привело к:
/usr/include/x86_64-linux-gnu/bits/huge_val.h:25: ошибка: ожидается указатель на функцию
или же
/usr/include/bits/huge_val.h:26:18: ошибка: отсутствует двоичный оператор перед токеном "("
Это связано с тем, что некоторые системные заголовки, такие как huge_val.h
используют макросы, такие как __GNUC_PREREQ
, которые определены в /usr/include/features.h
(подробнее об этом заголовке __GNUC_PREREQ
в этом вопросе SO).
В моем случае я впервые увидел эту ошибку, когда начал использовать опцию gcc -I, которая неожиданно заставила gcc выбрать каталог для включения моего проекта до того, как стандартные каталоги включения системы.
Ответ 3
Иногда вы получаете эту ошибку, если у вас есть -fno-operator-names
в флагах вашего компилятора. Я пострадала от точной ошибки при сборке json
, и это решило ее.