Ожидается, неквалифицированный-ID до '{' знак - PullRequest
2 голосов
/ 19 марта 2012

Я столкнулся со странной ситуацией. Насколько я понимаю, порядок включения заголовочных файлов не имеет большого значения, если я установил флаг #ifndef #define #endif для всех файлов .h.

Старые коды хиджры

#ifndef A_H
#define A_H
   blah blah blah
#endif

a.cc

#include "a.h"
blah blah blah

и выше коды работали нормально.

Теперь я добавил новый заголовок b.h

б.ч

#ifndef B_H
#define B_H
   blah blah blah 
#endif

новый a.cc

#include "a.h"
#include "b.h"
blah blah blah

Приведенный выше файл a.cc скомпилирован нормально. Однако, если я изменю a.cc на

новая версия a.cc 2

#include "b.h"
#include "a.h"
blah blah blah

скомпилировано не удалось с ошибкой: ожидаемый неквалифицированный идентификатор перед токеном «-».

Извините, я не могу воспроизвести ту же ошибку в крошечном примере. Ошибка компиляции привела к большому проекту. И если бы я тестировал в маленьком примере, созданном как выше. Это скомпилировано, но если я вернусь к проекту. Порядок директивы #include имеет значение. Я понятия не имею, где может возникнуть эта проблема. Любой, кто может дать мне подсказку, был бы очень полезен. Заранее спасибо

[Решено] Я решил проблему самостоятельно. Тем не менее, я думаю, что другие люди тоже могут застрять. Причина, по которой возникла проблема, была следующей:

в test.cc

const int var_undef = -1;
#define var_undef (-1)

Он компилируется, а если поменять местами эти две строки

#define var_undef (-1)
const int var_undef = -1

Он компилируется с ожидаемым безусловным идентификатором ошибки перед токеном "-", как я уже говорил.

1 Ответ

3 голосов
/ 19 марта 2012

Порядок включения имеет значение, конечно.Директива include в основном копирует и вставляет содержимое заголовка в текущий блок перевода.Если тип, необходимый для b.h, определен в a.h, вам необходимо включить a.h до b.h или, что еще лучше, включить a.h в b.h.

Предположим:

//a.h
struct A
{
};

//b.h
struct B : public A
{
};

//main.cc
#include "a.h"
#include "b.h"
int main()
{
   return 0;
}

Это будет компилироваться в порядке, поскольку A определено до B.Единица перевода в основном будет:

struct A
{
};
struct B : public A
{
};
int main() 
{
   return 0;
}

Если, однако, вы инвертируете порядок включений, вы получите:

struct B : public A
{
};
struct A
{
};
int main() 
{
   return 0;
}

, что, очевидно, является ошибкой.

Однако самый правильный способ сделать это - включить a.h в b.h:

//b.h
#include "a.h"
struct B : public A
{
};

Таким образом, любой, кто захочет включить b.h, может, не беспокоясь о других заголовках.

...