2009-11-16 7 views
2

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

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

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

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

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

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

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

+0

Какое имя использует? –

+5

показать кодz ... – Inverse

+3

Пожалуйста, введите код –

ответ

26

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

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

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

Плохие включают имена охранников (для файла «config.h»):

  • CONFIG_H
    • слишком общий
  • _CONFIG_H, CONFIG__H, CONFIG_H__, __CONFIG_H__ и т.д.
    • все reserved, все еще слишком общий
  • PROJECT_CONFIG_H
    • лучше, гораздо менее вероятно, чтобы дублировать в несвязанных проектов
    • , но до сих пор нет информации пути, легко дублировать в крупных проектах

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

  • PATE_20091116_142045
    • это <last name>_<date>_<time>
    • нет проекта, путь, имя файла информации даже необходима
    • легко набирает
      • Если ваш редактор имеет функцию вставки, вы можете «набрать» ее очень быстро
    • легко генерировать
      • включает в себя порядковый номер при генерации, если вам нужно создать более одного в секунду
    • сильной гарантией быть универсально уникальным
  • INCLUDE_GUARD_726F6B522BAA40A0B7F73C380AD37E6B
    • , полученный от фактического UUID
      • сильной гарантией быть универсально уникальным
    • если оказывается неожиданно, «INCLUDE_GUARD» хороший намек на то, что он, находясь на службе, чтобы поместить его в отдельном пространстве имен (хотя по соглашению, а не признан языком)
    • предварять имя проекта, если это необходимо (который часто требует проектных руководящих принципов для макросов)
    • легко написать свой собственный sample program генерировать
+6

#pragma once - лучший защитник (если поддерживается вашими целевыми компиляторами) – sbk

+4

За исключением #pragma вводит дебаты о поддержке и нестандартные, без дополнительной выгоды. Легко использовать включают охранники. – 2009-11-25 20:53:46

+1

Потенциальное дополнительное преимущество заключается в том, что компилятор мог собрать коллекцию имен файлов заголовков, которые когда-то использовались в #pragma, и даже никогда не открывать файл, а не открывать файл, читать все, анализировать и игнорировать его , Тем не менее, я использую оба и имею #pragma, однажды защищенный версией проверки компилятора ... –

3

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

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

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

+0

Как я уже сказал, все прекрасно компилируется, когда я помещаю мусор в качестве константы. –

+0

, тогда, звучит для меня, вы должны использовать мусор действительно (имя действительно не имеет значения), поскольку имя, вызывающее проблему, очевидно, объявлено где-то еще. Как упоминалось в другом ответе, константой может быть любое имя. Если область видимости только локальная, то не беспокойтесь и не держите свое рабочее мусорное имя. – Abel

+0

Я надеялся понять, почему это так. –

Смежные вопросы