Malaja
|
|
« : 18-06-2008 11:16 » |
|
Слов нет, посему просто констатация факта. Есть элемнтарный с++-проект без МФЦ. В нем 2 .cpp-файла (просто для читабельности - в одном основные функции, в другом все остальное) и 1 .h-файл. В cpp-шках стоит: #include "stdafx.h" #include "alldbtypes.h"
А в alldbtypes.h - все include-файлы + все необходимые общие переменные. Соответственно в лучших традициях все стоит в #ifndef ALLDBTYPES_IRI #define ALLDBTYPES_IRI #endif
При попытке собрать проект получаю - первый cpp-файл она собирает легко, а при попытке собрать второй: readTables.obj : error LNK2005: "void * henv" (?henv@@3PAXA) already defined in my_odbc_test.obj Бамс... У меня явно начался тормоз - я никак не пойму, почему??? Ведь ей же по-человечески сказали #ifndef! Я понимаю, что где-то что-то потеряла, но что-то не пойму что...
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #1 : 18-06-2008 11:35 » |
|
Где у тебя #endif в заголовочном файле стоит? Должен в самом низу (конце) стоять.
Как это "при попытке собрать второй"? Ты их по отдельности собираешь?
с #pragma once пробовала?
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #2 : 18-06-2008 11:40 » |
|
Malaja, думаю проще код показать, сразу ясно будет
|
|
|
Записан
|
С уважением Lapulya
|
|
|
Malaja
|
|
« Ответ #3 : 18-06-2008 12:05 » |
|
Джон, 1) #endif стоит в самом конце. 2) Собираю я не по отдельности - я просто неверно выразилась.. Я хотела сказать, что в окошке, в котором отображается процесс компиляции, я вижу, что первый файл идет без проблем, а на втором мне рассказывают сказки про повторное объявление переменных. 3) с #pragma once еще не пробовала. Сейчас попробую. Не спасло... lapulja, вот Код: #include "stdafx.h" #include "sql.h" #include "sqlext.h" #include <iostream.h>
#ifndef ALLDBTYPES_IRI #define ALLDBTYPES_IRI
struct FieldInfo { int m_nColNumber; char m_strFieldName[1024]; SDWORD m_nFieldType; int m_nCurIndInArray;
UCHAR m_strCharVal[10000]; WCHAR m_strWCharVal[10000]; long m_nSLongVal; unsigned long m_nULongVal; float m_fFloatVal; double m_fDoubleVal; } ;
SQLHANDLE hdbc = SQL_NULL_HDBC, henv = SQL_NULL_HDBC;
void readTable(); #endif
// my_odbc_test.cpp:
#include "stdafx.h" #include "alldbtypes.h"
int connect () { // ... }
void disconnect () { // ... } main() { connect(); readTable(); disconnect(); }
//readTables.cpp:
#include "stdafx.h" #include "alldbtypes.h"
void readTable() { //... }
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
McZim
|
|
« Ответ #4 : 18-06-2008 12:27 » |
|
зачем ты во всех трех файлах линкуеш (#include "stdafx.h")
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Malaja
|
|
« Ответ #5 : 18-06-2008 12:31 » |
|
McZim,
В проекте выставлены precompieled header files, т.е. если его не инклудировать, то при компиляции появляется ошибка: fatal error C1010: unexpected end of file while looking for precompiled header directive
Убирать эту установку мне не с руки, т.к. это впоследствии не только мой проектик будет (его надо будет отдать другим как пример).
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
Антон (LogRus)
|
|
« Ответ #6 : 18-06-2008 12:34 » |
|
McZim, это же VC++ есть такой там stdafx.h precompiled header в него обычно кидаются всякие инклюды общие для всего проекта
|
|
|
Записан
|
Странно всё это....
|
|
|
McZim
|
|
« Ответ #7 : 18-06-2008 12:39 » |
|
может так? #ifndef ALLDBTYPES_H_INCLUDED #define ALLDBTYPES_H_INCLUDED ... ... ... #endif // ALLDBTYPES_H_INCLUDED
хотя если это VC могу ошибаться.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Malaja
|
|
« Ответ #8 : 18-06-2008 12:53 » |
|
McZim, Смена имени константы ни к чему не привела - состояние больного стабильно тяжелое
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
Scorp__)
Молодой специалист
Offline
Пол:
|
|
« Ответ #9 : 18-06-2008 13:09 » |
|
Malaja, а скажи, sql.h и sqlext.h точно защищены от повторного включения?
|
|
|
Записан
|
- А Вы сами-то верите в привидения? - Конечно, нет, - ответил лектор и медленно растаял в воздухе.
|
|
|
Malaja
|
|
« Ответ #10 : 18-06-2008 13:13 » |
|
Scorp_, дело в том, что в сообщении о повторной декларации переменных говорится только о моих переменных, посему остальные хедеры я даже не проверяла, т.к. исхожу из того, что с этой стороны проблем быть не должно.
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
McZim
|
|
« Ответ #11 : 18-06-2008 13:15 » |
|
Malaja, хм, а как на счет того что твои хедеры могут несколько раз подключать остальные хедеры и дело не в том что ты неправильно защитила свои хедеры а как раз в том что ты несколько раз подключила другие.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #12 : 18-06-2008 13:38 » |
|
Ир, в h попробуй вот так сделать #ifndef ALLDBTYPES_IRI #define ALLDBTYPES_IRI
#include "sql.h" #include "sqlext.h" #include <iostream.h>
struct FieldInfo {
....
УБЕРИ stdafx.h из хидера. Его только в срр инклудируй.
|
|
« Последнее редактирование: 18-06-2008 13:40 от Джон »
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Scorp__)
Молодой специалист
Offline
Пол:
|
|
« Ответ #13 : 18-06-2008 13:48 » |
|
Да, действительно ошибка не там. Malaja, посмотрел код повнимательнее и вспомнил где видел похожую ситуацию: в "Стандартах программирования на С++". Рекомендация: "Не определяйте в заголовочном файле объекты со связыванием" В общем, в хедере надо сделать объявление extern SQLHANDLE hdbc; extern SQLHANDLE henv;
А инициализацию и объявление вынести в один из файлов реализации. Защита не работает, у тебя же не каскадное включение, в каждый cpp файл включается свой экземпляр хедера, а макрос за пределами модуля конечно не работает.
|
|
|
Записан
|
- А Вы сами-то верите в привидения? - Конечно, нет, - ответил лектор и медленно растаял в воздухе.
|
|
|
Malaja
|
|
« Ответ #14 : 18-06-2008 13:54 » |
|
Scorp_, проверила - там все чисто (как минимум #ifndef есть)
по поводу стандартов - я как-то запуталась окончательно: смотри, оба файла принадлежат одному проекту и используют одни и те же переменные. Далее, хедер должен включиться только как декларация типа "есть такая переменная в проекте". А сама переменная в разных местах устанавливается и используется. Это же та же самая инстанция! Или я неправа?
Джон, попробовала сразу - не спасает...
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
Malaja
|
|
« Ответ #15 : 18-06-2008 14:04 » |
|
Scorp_,
сейчас попробовала с extern - работает! Спасибочки за подсказку! Но почему без extern не работало, не пойму...
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
Malaja
|
|
« Ответ #16 : 18-06-2008 14:06 » |
|
ой, не дописала - пардон... Когда я все организую без хедеров - тогда все понятно, т.к. другой файл должен знать о существовании переменных. Посему в первом файле они объявляются по-человечески, а во втором только как extern. А тут...
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
Scorp__)
Молодой специалист
Offline
Пол:
|
|
« Ответ #17 : 18-06-2008 14:16 » |
|
Malaja, неа, один файл - это один модуль трансляции и компоновки, проект состоит из таких модулей. Хедер подключается к первому файлу, компоновщик видит переменную и определяет ее как объект. Потом компоновщик заканчивает с первым файлом и проделывает со вторым то же самое, но когда пытается определить объект для переменной, то обнаруживает что такой объект в проекте уже существует о чем тебе и сообщает.
То есть именно для объявления, что есть в проекте такая переменная нужно использовать рецепт с extern в хедере и реализацией в одном из cpp, этот объект будет виден по всему проекту.
Защита же нужна для другого случая: когда кто-то пишет свой класс или еще что-то и подключает в свой хедер твой. Затем кто-то третий, подключает сначала твой хедер, а потом тот второй (который уже включает твой). Вот здесь в пределах одного модуля защита срабатывает.
В общем, это разные инстанции ))
Дописываю пост )))
Когда очередь доходит до компоновщика, хедер уже прицеплен к cpp, и для компоновщика это одно целое. То есть, можно считать, что компоновщик все организует без хедеров сам )) (это чтобы не объяснять то, что интуитивно мне понятно, но словами выразить сложнее)
Может быть кто-то еще сможет подробнее объяснить работу компоновщика в этом случае и не запутаться в словах, а?
|
|
|
Записан
|
- А Вы сами-то верите в привидения? - Конечно, нет, - ответил лектор и медленно растаял в воздухе.
|
|
|
npak
|
|
« Ответ #18 : 18-06-2008 14:16 » |
|
Ирина, когда ты пишешь #include "bla-bla", то в текст твоего .cpp файла вставляется содержимое файла "bla-bla". В результате и в первом, и во втором файле появляется строка с определениями глобальных переменных SQLHANDLE hdbc = SQL_NULL_HDBC, henv = SQL_NULL_HDBC;
Линковщик обругал тебя по делу - в двух объектных файлах определены символы с одинаковыми именами. При линковке это запрещено - всякий символ должен разрешаться однозначно. Scort__), никто ничего не цепляет/подключает. Препроцессор заменяет директиву #include "bla-bla" на ТЕКСТ файла bla-bla. В стандарте прямым текстом сказано (параграф 16.2): A preprocessing directive of the form # include "q-char-sequence" new-line causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters. The named source file is searched for in an implementation-defined manner.
|
|
« Последнее редактирование: 18-06-2008 14:26 от npak »
|
Записан
|
|
|
|
Malaja
|
|
« Ответ #19 : 18-06-2008 14:29 » |
|
Все, ребята, огромное спасибо! Дошло!!! Это же не с++ со своими классами, это же с! И там таки каждый файл собирается по очереди, хоть они и сидят в одном проекте! Извините за беспокойство
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
npak
|
|
« Ответ #20 : 18-06-2008 14:37 » |
|
Ирина, в С++ у тебя все тоже самое - препроцессор и схема раздельной компиляции у них общие
|
|
|
Записан
|
|
|
|
Scorp__)
Молодой специалист
Offline
Пол:
|
|
« Ответ #21 : 18-06-2008 14:43 » |
|
npak, я знаю, что текст просто дописывается. Просто до компоновки происходит компиляция в объектный файл. Мне хотелось отразить и этот процесс в своей фразе.
|
|
|
Записан
|
- А Вы сами-то верите в привидения? - Конечно, нет, - ответил лектор и медленно растаял в воздухе.
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #22 : 18-06-2008 15:22 » |
|
npak, да, но в таком случае в срр будет вставлено #ifndef ALLDBTYPES_IRI #define ALLDBTYPES_IRI
...
SQLHANDLE hdbc = SQL_NULL_HDBC, henv = SQL_NULL_HDBC;
... #endif
Двух определений быть не должно. Хотя ошибка конечно в этом. Тему про extern мы уже где-то интенсивно обсуждали. Ирина имела ввиду C#
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Scorp__)
Молодой специалист
Offline
Пол:
|
|
« Ответ #23 : 18-06-2008 16:17 » |
|
Джон, но это будет вставлено в каждый cpp, и каждый cpp будет компилироваться и компоноваться отдельно от других, поэтому в каждом cpp макрос ALLDBTYPES_IRI не будет определен изначально.
|
|
|
Записан
|
- А Вы сами-то верите в привидения? - Конечно, нет, - ответил лектор и медленно растаял в воздухе.
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #24 : 18-06-2008 22:58 » |
|
Блиин, туплю по страшному. Scorp__), 100% прав.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Malaja
|
|
« Ответ #25 : 19-06-2008 08:23 » |
|
мда, когда руки набирают быстрее, чем думает голова, получаются нестыковочки Я имела в виду, что когда работаешь с классами, то такой ситуации просто не может быть, т.к. все функции-переменные принадлежат одному отдельно взятому классу. А как только начинаются глобальные переменные, так сразу же и начинается песенка про экстерн. Просто в нормальной жизни никаких глобальных переменных в нормальном с++-ном проекте при наличии классов не бывает.
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #26 : 19-06-2008 08:41 » |
|
Malaja, еще как бывают!!!
|
|
|
Записан
|
С уважением Lapulya
|
|
|
Malaja
|
|
« Ответ #27 : 19-06-2008 09:06 » |
|
в старых сплошь и рядом... И переделать невозможно, т.к. на эту работу никто не выделит время и деньги... Так что тут никуда не денешься. А в новых это дело просто не пропускается еще на стадии дизайна. Т.е. есть жесткое условие - не применять под страхом смертной казни А если программист не знает, как это обойти, должен спросить более опытных коллег - они подскажут.
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #28 : 19-06-2008 09:28 » |
|
Ир, на самом деле это не так. lapulya - прав. Загляни в любой свой MFC проект там ты всегда найдёшь нечто подобное: extern CMyApp theApp; Это глобальная инстанция твоей программы - объект, который должен быть создан. Конечно, если ты его не используешь в проге, то он хоть и будет без extern, но всё-равно глобальным.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Malaja
|
|
« Ответ #29 : 19-06-2008 09:56 » |
|
Джон, ну так theApp - это же уже почти родное, т.е. мелкомягкое ;_) А я имела в виду что-то введенное своими шаловливыми ручками
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
|