_s4 Так я ж тебе в который раз объясняю, что когда ты меняешь расширение на .hpp, файл 0002.hpp не учавствует напрямую в компиляции. Т.е. его код компилируется, как часть кода 0001.cpp. И так как он включается после #include <windows.h> то всё работает. если хочешь компилить его как отдельный модуль, впиши в начало 0002.cpp #include <windows.h> И вообще, precompiled headers используй.
2green нет. Объясню немного по другому. Почему когда я делаю так: Создаю win32 проект 0001, добавляю 2 .cpp файла, один главный, другой с чем угодно, выглядит примерно так: Код (Text): //0001.cpp #include <windows.h> #include "0002.cpp" int __stdcall wWinMain(param....) { func0001(); return 0; } //0002.cpp void func0001(void) { //... } Создаю win32 проект 0002, добавляю 2 файла - 0001.cpp, 0002.hpp(расширение всё равно какое) , один главный(0001.cpp), другой с чем угодно(0002.hpp), выглядит примерно так: Код (Text): //0001.cpp #include <windows.h> #include "0002.hpp" int __stdcall wWinMain(param....) { func0001(); return 0; } //0002.hpp void func0001(void) { //... } Проет 0002 собирается нормально, 0001 нет. Пишит много ошибок, каких я написал выше :/
_s4 Так происходит потому, что в первом(0001) проекте файл 0002.cpp компилируется как отдельный модуль, а во втором(0002) проекте файл 0002.hpp компилируется как часть 0001.cpp, т.е. НЕ как отдельный модуль. См. ещё раз #21. -- Точнне в первом проекте код файла 0002.cpp компилируется дважды: как отдельный модуль, и как часть 0001.cpp. Убери #include "0002.cpp", иначе будут ещё и ошибки линковки.
2green спасибо вроде понял, всем спасибо. Значит с помощью #include нельзя компилировать 2 и больше cpp файлов ? А если в краце что такое и в чём преимущество перед дерективой #include precompiled headers ? Не разу не использовал если честно.
можно, но инклуде тупо вставляет в текст код из файла. Но лучше так не делать. include обычно юзается для включения хидеров, в которых по правилам хорошего тона не хранится ни код, ни данные, а только элементы не занимающие память. precompiled headers компилируются один раз в начале компиляции, и пока не изменишь в нём чего-нить перекомпиляция не нужна, а вот обычные хидеры "компилируются" каждый раз.
2n0name спасибо, всё ясно, хм странно только я вот например привык исходник на много файлов разбивать, к примеру в файле file.* ф-ции для работы с файлами итд, это чтоже ? я злой враг хорошего тона ? На счёт precompiled headers, хм класс, буду использовать теперь .
_s4 Хорошая практика, но только это должны быть непосредственно компилируемые файлы (.cpp), а не хедеры (.h, .hpp). А хедеры для того, чтобы включать туда всяческие определения, декларации - т.е. общие части нескольких .cpp. Упрощённо, реализация помещается в .cpp, а её интерфейс - в хедер, т.к. к нему может потребоваться доступ из других .cpp.
_s4 Можно, всё можно. Но в срр обычно кладут код, а в h/hh/hxx/hpp - объявления. срр компилируются, h* - включаются в срр. Если работаешь с проектами, то срр автоматически компилируются, если не задать обратного. Если с командной строкой - их надо указывать в строке для cl ("cl /nologo 01.cpp 02.cpp 03.cpp"). Precompiled headers используются для одноразовой компиляции стандартных заголовочных файлов, которые используются в проекте. Если много срр файлов, то это может уменьшить скорость компиляции, иначе не стоит связываться.
n0name Пока template export не реализовано в передовых компиляторах, в хидеры приходится класть шаблоны.
Продолжение: 1) На счёт оптимизации: Я всё конечно понимаю, но почему visual studio бесспроса оптимизирует что то на своё усмотрение. Я за, но почему он вставляет инлайн ф-ции вместо обычных итд ? Например код на си что то вроде этого: Код (Text): void func0001(void) { SYSTEMTIME stime; GetSystemTime(&stime); } void __main(void) { func0001(); ExitProcess(0); } Сгенерированный код: Код (Text): 00401000 >$ 83EC 10 SUB ESP,10 00401003 . 8D0424 LEA EAX,DWORD PTR SS:[ESP] 00401006 . 50 PUSH EAX 00401007 . FF15 04204000 CALL DWORD PTR DS:[<&KERNEL32.GetSystemTime>] 0040100D . 6A 00 PUSH 0 0040100F . FF15 00204000 CALL DWORD PTR DS:[<&KERNEL32.ExitProcess>]
_s4 Почему без спроса? Отключи оптимизацию, не будет инлайнить. Или управляй сам ею через #pragma optimize.
Ок спасибо. ой, извиняюсь, полез посмотреть только что какой у меня уровень оптимизации стоит и обратил внимание на такой пункт в меню - Inline Function Expansion - Default Only __inline (/Ob1) Any Suitable (/Ob2) Теперь всё стало понятно А можно как нибуть по человечески конвертировать вызов в стиле си (__cdecl) в __stdcall ? Чтобы избежать утечки памяти связанной с некоторыми API каторые в стиле си вызываются ? Или может какой нибуть другой способ есть ? Я что то не могу припомнить как можно манипулировать регистрами в си, без асм вставок в код ? Я вот про это, к примеру wsprintf(A/W) Код (Text): wsprintf(buf,TEXT("%d"),v); // Тут вроде надо esp+12 или нет ? В голову только вот такое пришло, я не извращенец ;))) : int (__stdcall *_wsprintf) (LPTSTR lpOut,LPCTSTR,...) = wsprintf; // но это не помогло... :( Спасибо
К стати в MSDN написано, что ...,the C compiler performs this task. Посмотрел в отладчике - ни фига он не выполняет...
_s4 > А как же быть ? Определять количество параметров из самих параметров. Можно передавать количество аргументов через параметр. Можно уловиться с признаком окончания цепочки параметров. Но это очень стремно. Используй статические механизмы. Как вариант - потоки.