Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Incude пересекаются?


Автор: Guest 24.10.2005, 13:46
Привет, All!

разъясните правило размещения #include
у меня при таком размещениии выдает ошибку компиляции:
Код

// file1.h
#include "file2.h"
...
// file2.h
#include "file1.h"
...

а при таком компилится нормально:
Код

// file1.cpp
#include "file2.h"
...
// file2.cpp
#include "file1.h"
...

Автор: Darhazer 24.10.2005, 13:52
Наверника у тебя просто в .h нет защита от повторного include-дa
При этом получаеться в первом случае

Код
//file1.h
#include "file2.h"
//--> это транслируеться до
#include "file1.h"
....
//т.е. в результате:
#include "file1.h"
//дефиниция file1.h
#include "file1.h"
//дефиниция file1.h
#include "file1.h"
//дефиниция file1.h
...

рекурсивний include!

Во втором случае у тебя просто у каждий .cpp
Код

#include file1.h
#include file2.h


Чтоб неполучаться рекурсивний include, нужно сделать:

Код

//file1.h

#ifndef __FILE1_H__
#define __FILE1_H__

//сам файл

#endif


Во втором тоже самое, только __FILE1_H__ должен быт уникальном идентификаторе
Тогда не получиться рекурсия и можно сделать так:

Код

// file1.h
#include "file2.h"
...
// file2.h
#include "file1.h"
...

Автор: Dark Elf 24.10.2005, 13:53
Используй #ifdef и #ifndef (или в коде file1.h и в коде file2.h ставь в самом начале #pragma once)

Автор: Guest 24.10.2005, 14:00
я семеркой пользуюсь, там при создании класса #pragma once автоматом выставляется в начале хедера (#pragma once стоит в начале всех хедеров) или её ещё и в cpp'ишник пихать нужно

может какой флаг не выставлен?

Автор: srd 24.10.2005, 14:29
#pragma once и #if/#endif не для этого предназначены.
Цитата(Guest @ 24.10.2005, 21:46)

// file1.h
#include "file2.h"
...
// file2.h
#include "file1.h"
...

Так делать нельзя. Препроцессор заменяет #include на содержимое подключаемого файла. Когда препроцессор парсит file1.h, он натыкается на #include и пытается подставить вместо него содержимое file2.h. Во время разбора file2.h он натыкается опять на #include, но вставить файл в сам себя препроцессор не может, на что и жалуется.

Добавлено @ 14:33
Нет, я ошибся. Фокус со стражами включения здесь помогает.

Автор: pablo 24.10.2005, 14:42
[/b]srd[/b] а #pragma once часом не мелкософтская фишка ? т.е сработает нод *nix ами ?

Автор: srd 24.10.2005, 14:46
В gcc #pragma once - deprecated.
Я обычно использую оба варианта
Код

#ifndef FILENAME_H_INCLUDE_
#define FILENAME_H_INCLUDE_

#if _MSC_VER > 1020
#pragma once
#endif

// тут 20 мегабайт кода

#endif /* FILENAME_H_INCLUDE_ */

smile

Автор: Guest 24.10.2005, 16:08
НАРОД, я конечно рад что вас так затронула данная тема, но всеже, позвольте вернуться к изначальному вопросу, почему подобное поведение проявляется и при #pragma once в начале каждого хедера?


надеюсь на конкретные ответы, спасибо

Автор: srd 24.10.2005, 16:18
А хамить зачем? Для того минимума информации, который ты предоставил, ответ Darhazer был исчерпывающим. Если у тебя по прежнему лезут ошибки, то показывай код и текст ошибок. Телепатов тут нет.

Автор: Guest 24.10.2005, 17:06
уважаемый srd где в моем вопросе вы увидели грубость?

будь вы хоть и телепатом но я слабо представляю как можно выложить настройки VS в форум, а у меня все больше складывается ощущение что проблема в них

а исходники, в интересующем нас фрагменте описаны в самом начале топика, могу повторить (с небольшим уточнением):
Код

// не работающий вариант
// file1.h
#pragma once
#include "file2.h"
...
// file2.h
#pragma once
#include "file1.h"
...


Код

// работающий вариант

// file1.h
#pragma once
...
// file1.cpp
#include "file2.h"
...
// file2.h
#pragma once
...
// file2.cpp
#include "file1.h"
...

Автор: Earnest 25.10.2005, 18:28
Рекурсивное вложение файлов запрещено в любом случае, какие прагмы не ставь.
И вообще, это ОЧЕНЬ ПЛОХОЙ СТИЛЬ!
Есть простое правило - если заголовочный файл можно не включать - его НЕ НУЖНО включать (в другой заголовочный файл). Есть весьма ограниченный перечень случаев, когда это действительно необходимо, и когда нельзя обойтись forward declarations, ну и иногда (в локальных случаях) это удобно, и можно уступить собственной лени. smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)