Краткое резюме: Код не является допустимым C ++, хотя есть некоторая неясность относительно того, должен ли он быть.Использование void
вместо VOID
или использование пустых скобок позволит избежать ошибки.
Я думаю, что это ошибка в g ++.
Я думал,это была ошибка в g ++.Теперь я убежден, что это не так, хотя я утверждаю, что было бы лучше сделать это предупреждение, а не фатальную ошибку.
Обычно в C ++ функция без параметров объявляется с пустыми скобками:
int foo();
В качестве уступки совместимости с C, C ++ также допускает создание прототипа в стиле C, используя void
, чтобы указать, что функция не имеет параметров (поскольку пустые скобки означают что-то еще в C):
int bar(void);
g ++ интерпретируется так, что void
в этом синтаксисе здесь не относится к неполному type void
;скорее он обрабатывает его как специальный синтаксис с отдельным использованием ключевого слова.
Я думаю, вам нужно изменить файл заголовка, чтобы g ++ его принял.
gcc принимает егокак действительный C, но это не полезно, если вам нужно #include
из исходного файла C ++ - если только вы не напишите обертку C и не вызовете ее из своего кода C ++, что может быть приемлемым обходным путем.
(Между прочим, я ненавижу typedefs как этот. Какова цель typedef void VOID;
? Автор думал, что void
был слишком запутанным? Я подозреваю, что это для совместимости с очень старыми компиляторами C, которые не поддерживалиvoid
, но необходимость в этом давно миновала.)
Вот соответствующее описание из последней версии стандарта ISO C ++ 2011 (8.3.5 [dcl.fct]):
Параметр-объявление-предложение определяет аргументы, которые могут быть указаны, и их обработку при вызове функции.[...] Если параметр-объявление-предложение пуст, функция не принимает аргументов.Список параметров (void)
эквивалентен пустому списку параметров.За исключением этого особого случая, void
не должен быть типом параметра (хотя типы, производные от void
, такие как void*
, могут).
Это означает, что ключевое слово void
в int bar(void);
относится к типу void
. Поскольку имя typedef является синонимом для именованного типа, int bar(VOID);
должно быть в равной степени допустимым. Было бы наиболее целесообразно, чтобы имя typedef, например VOID
, было принято вместо void
,но формулировка стандарта фактически относится к ключевому слову void
, а не к типу.
Вся цель разрешения (void)
- совместимость с Си.Просто чтобы добавить к путанице, стандарт ISO C 1990 года требует ключевое слово void
;стандарты C 1999 и 2011 годов изменили формулировку, позволив вместо этого использовать typedef.Ответ на Отчет о дефектах C ++ # 577 подтверждает, что в текущей формулировке требуется ключевое слово void
, и предлагает изменение, которое разрешит typedef, но это изменение пока отсутствует ни в одном стандарте ISO C ++.Вероятно, он появится в первом Техническом исправлении для C ++ 2011, когда бы он ни был опубликован.
Спасибо another.anon.coward за поиск существующего gcc отчета об ошибках .Я добавил слишком подробный комментарий о том, что код действителен, и сообщение об ошибке не должно создаваться, и более поздний комментарий, в котором говорится, что код недействителен, но предупреждение будет более уместным, чем фатальная ошибка.
Тем временем я предлагаю связаться с поставщиком этого sense4.h
заголовочного файла.Если они намеревались сделать это #include
d только из кода на C, то с этим нет никаких реальных проблем (кроме плохого стиля IMHO);в противном случае они могут рассмотреть возможность использования #ifdef __cplusplus
, объявив функции с (void)
в C и с ()
в C ++.И вы можете пойти дальше и сделать это самостоятельно.Независимо от того, должен ли g ++ принять код или нет, с некоторыми изменениями это будет допустимый C, допустимый C ++, приемлемый как для gcc, так и для g ++, и лучший стиль.
Если вы прочитали это далеко и вы еще не спите, я впечатлен.