Visual studio 2005

Тема в разделе "LANGS.C", создана пользователем _s4, 7 май 2007.

  1. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    _s4
    Так я ж тебе в который раз объясняю, что когда ты меняешь расширение на .hpp, файл 0002.hpp не учавствует напрямую в компиляции.
    Т.е. его код компилируется, как часть кода 0001.cpp. И так как он включается после
    #include <windows.h>
    то всё работает.

    если хочешь компилить его как отдельный модуль, впиши в начало 0002.cpp
    #include <windows.h>

    И вообще, precompiled headers используй.
     
  2. _s4

    _s4 New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2006
    Сообщения:
    58
    2green нет. Объясню немного по другому. Почему когда я делаю так:
    Создаю win32 проект 0001, добавляю 2 .cpp файла, один главный, другой с чем угодно, выглядит примерно так:

    Код (Text):
    1. //0001.cpp
    2.  
    3. #include <windows.h>
    4. #include "0002.cpp"
    5.  
    6. int __stdcall wWinMain(param....)  {
    7.  
    8.   func0001();
    9.  
    10.   return 0;
    11. }
    12.  
    13. //0002.cpp
    14.  
    15. void func0001(void)  {
    16.   //...
    17. }
    Создаю win32 проект 0002, добавляю 2 файла - 0001.cpp, 0002.hpp(расширение всё равно какое) , один главный(0001.cpp), другой с чем угодно(0002.hpp), выглядит примерно так:

    Код (Text):
    1. //0001.cpp
    2.  
    3. #include <windows.h>
    4. #include "0002.hpp"
    5.  
    6. int __stdcall wWinMain(param....)  {
    7.  
    8.   func0001();
    9.  
    10.   return 0;
    11. }
    12.  
    13. //0002.hpp
    14.  
    15. void func0001(void)  {
    16.   //...
    17. }
    Проет 0002 собирается нормально, 0001 нет. Пишит много ошибок, каких я написал выше :/
     
  3. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    _s4
    Так происходит потому, что в первом(0001) проекте файл 0002.cpp компилируется как отдельный модуль, а во втором(0002) проекте файл 0002.hpp компилируется как часть 0001.cpp, т.е. НЕ как отдельный модуль.
    См. ещё раз #21.
    --
    Точнне в первом проекте код файла 0002.cpp компилируется дважды: как отдельный модуль, и как часть 0001.cpp. Убери #include "0002.cpp", иначе будут ещё и ошибки линковки.
     
  4. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    инклудить компилируемые файлы моветон.
     
  5. _s4

    _s4 New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2006
    Сообщения:
    58
    2green спасибо вроде понял, всем спасибо. Значит с помощью #include нельзя компилировать 2 и больше cpp файлов ?
    А если в краце что такое и в чём преимущество перед дерективой #include precompiled headers ? Не разу не использовал если честно.
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    можно, но инклуде тупо вставляет в текст код из файла. Но лучше так не делать. include обычно юзается для включения хидеров, в которых по правилам хорошего тона не хранится ни код, ни данные, а только элементы не занимающие память.
    precompiled headers компилируются один раз в начале компиляции, и пока не изменишь в нём чего-нить перекомпиляция не нужна, а вот обычные хидеры "компилируются" каждый раз.
     
  7. _s4

    _s4 New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2006
    Сообщения:
    58
    2n0name спасибо, всё ясно, хм странно только я вот например привык исходник на много файлов разбивать, к примеру в файле file.* ф-ции для работы с файлами итд, это чтоже ? я злой враг хорошего тона ? :dntknw: На счёт precompiled headers, хм класс, буду использовать теперь :) .
     
  8. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    _s4
    Хорошая практика, но только это должны быть непосредственно компилируемые файлы (.cpp), а не хедеры (.h, .hpp). А хедеры для того, чтобы включать туда всяческие определения, декларации - т.е. общие части нескольких .cpp.
    Упрощённо, реализация помещается в .cpp, а её интерфейс - в хедер, т.к. к нему может потребоваться доступ из других .cpp.
     
  9. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    _s4
    Можно, всё можно. Но в срр обычно кладут код, а в h/hh/hxx/hpp - объявления. срр компилируются, h* - включаются в срр.

    Если работаешь с проектами, то срр автоматически компилируются, если не задать обратного. Если с командной строкой - их надо указывать в строке для cl ("cl /nologo 01.cpp 02.cpp 03.cpp").

    Precompiled headers используются для одноразовой компиляции стандартных заголовочных файлов, которые используются в проекте. Если много срр файлов, то это может уменьшить скорость компиляции, иначе не стоит связываться.
     
  10. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    n0name
    Пока template export не реализовано в передовых компиляторах, в хидеры приходится класть шаблоны.
     
  11. _s4

    _s4 New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2006
    Сообщения:
    58
    Всё, теперь точно всё понятно, всем спасибо :)
     
  12. _s4

    _s4 New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2006
    Сообщения:
    58
    Продолжение:
    1) На счёт оптимизации:

    Я всё конечно понимаю, но почему visual studio бесспроса оптимизирует что то на своё усмотрение. Я за, но почему он вставляет инлайн ф-ции вместо обычных итд ? Например код на си что то вроде этого:
    Код (Text):
    1. void func0001(void) {
    2. SYSTEMTIME stime;
    3.  
    4.     GetSystemTime(&stime);
    5. }
    6.  
    7.  
    8. void __main(void)   {
    9.  
    10.     func0001();
    11.  
    12.     ExitProcess(0);
    13. }
    Сгенерированный код:
    Код (Text):
    1. 00401000 >$ 83EC 10        SUB ESP,10
    2. 00401003  . 8D0424         LEA EAX,DWORD PTR SS:[ESP]
    3. 00401006  . 50             PUSH EAX                                            
    4. 00401007  . FF15 04204000  CALL DWORD PTR DS:[<&KERNEL32.GetSystemTime>]      
    5. 0040100D  . 6A 00          PUSH 0                                                
    6. 0040100F  . FF15 00204000  CALL DWORD PTR DS:[<&KERNEL32.ExitProcess>]
     
  13. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    _s4
    Почему без спроса? Отключи оптимизацию, не будет инлайнить. Или управляй сам ею через #pragma optimize.
     
  14. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    _s4

    А он и не обязан не инлайнить если ты не бедешь адрес функции.
     
  15. _s4

    _s4 New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2006
    Сообщения:
    58
    Ок спасибо. ой, извиняюсь, полез посмотреть только что какой у меня уровень оптимизации стоит и обратил внимание на такой пункт в меню -
    Inline Function Expansion - Default
    Only __inline (/Ob1)
    Any Suitable (/Ob2)
    Теперь всё стало понятно :)

    А можно как нибуть по человечески конвертировать вызов в стиле си (__cdecl) в __stdcall ? Чтобы избежать утечки памяти связанной с некоторыми API каторые в стиле си вызываются ? Или может какой нибуть другой способ есть ? Я что то не могу припомнить как можно манипулировать регистрами в си, без асм вставок в код ? Я вот про это, к примеру wsprintf(A/W)
    Код (Text):
    1. wsprintf(buf,TEXT("%d"),v);
    2. // Тут вроде надо esp+12 или нет ?
    3. В голову только вот такое пришло, я не извращенец ;))) :
    4. int (__stdcall *_wsprintf) (LPTSTR lpOut,LPCTSTR,...) = wsprintf;
    5. // но это не помогло... :(
    Спасибо :)
     
  16. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Функции с произвольным числом параметров не могут быть __stdcall
     
  17. _s4

    _s4 New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2006
    Сообщения:
    58
    2_DEN_ хм, только что вдумался, и правда... :/
    А как же быть ?
     
  18. _s4

    _s4 New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2006
    Сообщения:
    58
    К стати в MSDN написано, что ...,the C compiler performs this task. Посмотрел в отладчике - ни фига он не выполняет...
     
  19. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    _s4

    > А как же быть ?

    Определять количество параметров из самих параметров. Можно передавать количество аргументов через параметр. Можно уловиться с признаком окончания цепочки параметров. Но это очень стремно. Используй статические механизмы. Как вариант - потоки.
     
  20. _s4

    _s4 New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2006
    Сообщения:
    58