Добавление включения защиты нарушает сборку

Я добавил #ifndef .. # define .. # endif в файл моего проекта, и компилятор не работает. Как только я удаляю его или добавляю любое другое имя в определение, он компилируется нормально. В чем может быть проблема?

Похоже, файл уже объявлен, но я не знаю где. Я в порядке, просто удаляю его, но я действительно хочу знать, почему это происходит.

error: expected class-name before ‘{’ token
error: ‘QDesignerFormEditorInterface’ has not been declared

И еще пара ошибок.

На самом деле я использую пример из Qt, «Пример настраиваемого плагина виджета».

Разница в том, что я использую свой собственный класс для настраиваемого виджета (файлы .h, .cpp и .ui).

Возможно, это связано с файлом, в котором есть 2 включения, хотя в примере это было сделано именно так.


person yan bellavance    schedule 16.11.2009    source источник
comment
Опишите файл. Объясните, какой #ifndef вы добавляете и почему. Если это стандартная защита включения, и вы все делаете правильно, то вы, вероятно, дублируете имя защиты включения. Найдите его в своей кодовой базе и используйте в будущем более разные имена (имена, основанные непосредственно на имени всего файла, обычно безопасны).   -  person David Thornley    schedule 16.11.2009
comment
Ошибка не в сборке, а всего в одной единице компиляции. Это ошибка времени компиляции, поэтому добавление модуля, который не удалось скомпилировать, определенно было возможно.   -  person Wolf    schedule 13.11.2017


Ответы (2)


Используется ли этот макрос в качестве защиты включения? Если это так, похоже, вы дублируете имя, используемое в другом месте. Это обычная проблема, когда люди не думают об объеме, который должен иметь защитник включения, вы должны включить в него гораздо больше информации, чем просто имя файла.

Включите охранные цели:

  • генерировать один раз при создании заголовка
  • никогда не придется думать снова
  • шанс дублирования меньше, чем ваш шанс выиграть в лотерею

Неправильно включают имена охранников (для файла "config.h"):

  • CONFIG_H
    • much too general
  • _CONFIG_H, CONFIG__H, CONFIG_H__, __CONFIG_H__, etc.
  • PROJECT_CONFIG_H
    • better, much less likely to duplicate in unrelated projects
    • но по-прежнему нет информации о пути, легко дублируется в больших проектах

Хорошо включать имена охранников (для файла "config.h"):

  • PATE_20091116_142045
    • that's <last name>_<date>_<time>
    • информация о проекте, пути и имени файла даже не требуется
    • easy to type
      • if your editor has an insert-date feature, you can "type" it very fast
    • easy to generate
      • include a sequence number when generating, if you need to generate more than one per second
    • надежная гарантия универсальной уникальности
  • INCLUDE_GUARD_726F6B522BAA40A0B7F73C380AD37E6B
    • generated from an actual UUID
      • strong guarantee of being universally unique
    • если он появляется неожиданно, "INCLUDE_GUARD" является хорошим намеком на то, что это такое, и служит для помещения его в отдельное пространство имен (хотя по соглашению, а не распознается языком)
    • при желании добавьте имя проекта (что часто требуется руководящими принципами проекта для макросов)
    • легко написать собственную программу-образец для создания
person Community    schedule 16.11.2009
comment
#pragma once - лучшая защита включения (если поддерживается вашими целевыми компиляторами) - person sbk; 16.11.2009
comment
За исключением того, что #pragma вводит дискуссию о поддержке и нестандартности без каких-либо дополнительных преимуществ. Легко использовать, включая охранников. - person ; 25.11.2009
comment
Потенциальным дополнительным преимуществом является то, что компилятор может создать коллекцию имен файлов заголовков, в которых когда-то использовалось #pragma, и никогда даже не открывать файл снова, вместо того, чтобы открывать файл, читать его все, анализировать и игнорировать. Тем не менее, я использую оба и имею #pragma, однажды защищенную проверкой версии компилятора ... - person Len Holgate; 25.11.2009
comment
Компилятор может сделать это с помощью включаемых охранников. GCC делал это в течение многих лет, и я слышал, что MSVC тоже. Существенная проблема заключается в том, как обрабатывать такие вещи, как ссылки (как символьные, так и жесткие) - #pragma не работает, но включить охранники работают. - person ; 26.11.2009

Если вы добавите #ifndef для уже определенной константы, она всегда будет иметь значение true. Вы говорите «файл объявлен», но файлы не объявляются. Это действительно константа, которую вы помещаете после #ifndef, которую вы должны проверять. Выполните простой поиск по всему дереву исходных текстов и дважды проверьте, в каком порядке отображается ваш текущий #define.

И конечно: правильный ли ваш код? Попробуйте использовать бессмысленное имя в качестве константы и поместите #endif сразу после него: если оно по-прежнему ошибочно, у вас есть опечатки (вставьте свой код, если да). См. Также этот пост.

PS: Я вижу, что Дэвид Торнли вводил аналогичный совет в комментарии ... извините, если это дублирует информацию в этой теме.

person Abel    schedule 16.11.2009
comment
как я уже сказал, все компилируется нормально, когда я помещаю мусор в качестве константы. - person yan bellavance; 16.11.2009
comment
тогда, как мне кажется, вы действительно должны использовать мусор (имя действительно не имеет значения), поскольку имя, вызывающее проблемы, очевидно, уже объявлено в другом месте. Как упоминалось в другом ответе, константа может иметь любое имя. Если область видимости только локальная, тогда не беспокойтесь и сохраните свое рабочее имя, похожее на хлам. - person Abel; 16.11.2009
comment
Я надеялся понять, почему это так. - person yan bellavance; 17.11.2009
comment
Может, я не понял. Обязательно внимательно ознакомьтесь с ответом Пейта, он довольно обширен. Если XYZ определен, а у вас есть #ifndef XYZ, он всегда будет терпеть неудачу. Если вы хотите обратное, используйте имя, которое не определено. Боюсь, это все, почему. - person Abel; 17.11.2009
comment
Хорошо, я посмотрю на это ... извините, я на работе, и у меня сегодня не было времени, чтобы посмотреть на это. Спасибо за ваши ответы, хотя - person yan bellavance; 17.11.2009