Почему порядок моего #includes имеет значение? (C ++) - PullRequest
1 голос
/ 15 мая 2009

Я создал заголовочный файл с именем «list_dec.h», поместил его в папку «C: \ Headers» и настроил мой компилятор на включение файлов из «C: \ Headers», так что теперь я могу делать вещи как

#include<list_dec.h>
int main(){return(0);}

но когда я пытаюсь сделать что-то вроде

#include<iostream>
#include<list_dec.h>
int main(){return(0);}

Я получаю сообщение об ошибке (ничего особенного, просто огромный список синтаксических ошибок в "list_dec.h", который, как я знаю, нереален, потому что я смог скомпилировать его как файл main.cpp и .h файл в отдельном проекте). Однако, когда я меняю порядок, «list_dec.h» находится сверху:

#include<list_dec.h>
#include<iostream>
int main(){return(0);}

все ошибки исчезают. Так почему же порядок ошибки имеет значение?

NB. Насколько я знаю, это происходит, когда я использую "list_dec.h" со всеми заголовочными файлами, но я абсолютно уверен, что файлы, в которых он встречается:

#include<iostream>
#include<vector>
#include<time.h>
#include<stdlib.h>

РЕДАКТИРОВАТЬ: это ошибки, которые я получаю, когда «list_dec.h» находится ниже любого другого заголовка:

c:\headers\list_dec.h(14) : error C2143: syntax error : missing ')' before 'constant'
        c:\headers\list_dec.h(51) : see reference to class template instantiation 'list<T,limit>' being compiled
c:\headers\list_dec.h(14) : error C2143: syntax error : missing ';' before 'constant'
c:\headers\list_dec.h(14) : error C2059: syntax error : ')'
c:\headers\list_dec.h(14) : error C2238: unexpected token(s) preceding ';'
c:\headers\list_dec.h(69) : warning C4346: 'list<T,limit>::{ctor}' : dependent name is not a type
        prefix with 'typename' to indicate a type
c:\headers\list_dec.h(69) : error C2143: syntax error : missing ')' before 'constant'
c:\headers\list_dec.h(69) : error C2143: syntax error : missing ';' before 'constant'
c:\headers\list_dec.h(69) : error C2988: unrecognizable template declaration/definition
c:\headers\list_dec.h(69) : error C2059: syntax error : 'constant'
c:\headers\list_dec.h(69) : error C2059: syntax error : ')'
c:\headers\list_dec.h(78) : error C2065: 'T' : undeclared identifier
c:\headers\list_dec.h(78) : error C2065: 'limit' : undeclared identifier
c:\headers\list_dec.h(78) : error C2065: 'T' : undeclared identifier
c:\headers\list_dec.h(78) : error C2065: 'limit' : undeclared identifier
c:\headers\list_dec.h(79) : error C2143: syntax error : missing ';' before '{'
c:\headers\list_dec.h(79) : error C2447: '{' : missing function header (old-style formal list?)

Если это поможет, это строки, упомянутые в ошибках (14, 69, 78 и 79):

Строка 14: list(const T& NULL); (A constructor for "list" class)

Строка 69: inline list<T, limit>::list(const T& NULL): (Definition for the constructor, also, the colon at the end is intentional, It part of the definion ie: void x(int n): VAR(n).)

Строка 78: inline list<T, limit>::list(const list<T, limit>& lst) (def for the copy constructor)

Строка 79: { (the begining of the list-copy contructor)

И многие люди хотят видеть начало "list_dec.h":

template<class T, size_t limit>
class list

NB. Это не первые строки, но я думаю, что именно в этом и заключается проблема, строки перед ними - просто перечисление, называемое "err".

РЕДАКТИРОВАТЬ: просто примечание, "list_dec.h" не содержит включений, определяет, ifdefs, или что-либо предшествует с "#". Помимо перечисления он содержит только объявление класса «list» и определения функций-членов класса «list».

Ответы [ 5 ]

10 голосов
/ 15 мая 2009

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

В ответ на отправленные вами сообщения об ошибках символ NULL часто используется как макрос препроцессора для числа 0. Это позволяет легко использовать его в качестве нулевого указателя. Поэтому это:

list(const T& NULL);

Может быть преобразован в эту синтаксическую ошибку препроцессором:

list(const T& 0);

Измените имя параметра на другое, отличное от NULL.

3 голосов
/ 15 мая 2009

Обратите внимание, что здесь:

Line 14: list(const T& NULL); (A constructor for "list" class)

NULL - это имя стандартного макроса - если стандартный файл заголовка включен до list_dec.h, это, скорее всего, приведет к определению NULL, что, в свою очередь, приведет к тому, что ваш код будет выглядеть примерно так в компиляторе :

list(const T& 0);

Константа 0, указанная выше, делает строку C ++ нечеткой. Вы можете получить больше информации, указав вашему компилятору создать предварительно обработанный выходной файл.

2 голосов
/ 15 мая 2009

Фактические ошибки дадут более конкретную подсказку, но это означает, что в вашем включаемом файле есть что-то, что испортило сканирование для следующего. Наиболее распространенной вещью может быть какой-то неключающий # -направление, например, #if отсутствует его #endif.

2 голосов
/ 15 мая 2009

Предположительно list_dec.h работает с макросом, который определен в этих других заголовках (или некоторых заголовках, которые они в свою очередь включают) - трудно сказать, какой из них не видит первое сообщение об ошибке и соответствующую часть list_dec.h!

1 голос
/ 15 мая 2009

Если ошибки носят случайный характер, это может быть пропущенная точка с запятой. Компилятор обычно останавливается на этом, но иногда вам везет.

В противном случае конфликтующие имена или определения. Например, есть ли у вас что-нибудь с именем std?

...