Проблема компиляции в VS 2005

Тема в разделе "LANGS.C", создана пользователем Asterix, 20 окт 2006.

  1. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    я и так знал что не прокатит, ну просто проверил чтоб снять интерес
    *((char *)dest + i) ^= *((char *)dest + i);
    та же байда, компилятор далеко не дурак, он видимо логику анализирует.
     
  2. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Quantum
    И что это дает? Я уже пробовал, убрал /NODEFAULTLIB
    изменил код на
    OSVERSIONINFO osvi = {0};
    вызывается здоровая memset, и еще куча ненужного мне кода попадает в бинарник,
    если линковать статически, если динамически то еще хуже в импорт попадает msvcr80.dll
     
  3. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Блин, какой он умный, этот компилятор, сил нет :)
    А ассемблерные вставки он тоже может анализировать?

    P.S.
    Если он и вставку распознает, тогда может ему просто поручить самому написать программу?
     
  4. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    ну асм вставки не умеет анализировать, такой код катит
    Код (Text):
    1. void _test(void* dest, unsigned long len)
    2. {
    3.     __asm
    4.     {
    5.         push edi
    6.         xor eax, eax
    7.         mov edi, dest
    8.         mov ecx, len
    9.         cld
    10.         rep stosb
    11.         pop edi
    12.     }
    13.     return;
    14. }
    но мы же все-таки на С/C++ пишем, не хотелось прибегать к таким "запрещенным" методам ;)
     
  5. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Asterix
    Короче, чтоб полный код был таким:
    Код (Text):
    1. int CheckOS()
    2. {
    3.     OSVERSIONINFO osvi;
    4.  
    5.     memset(&osvi, 0, sizeof(OSVERSIONINFO));
    6.     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    7.     if ( GetVersionEx(&osvi) )
    8.         return osvi.dwPlatformId == VER_PLATFORM_WIN32_NT;
    9.     return 0;
    10. }
    Этот ключ не должен ни на что тут влиять, т.к. инлайном занимается компилятор, а не линкер, хотя я уже начинаю сомневаться :)
     
  6. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Quantum

    сделал, и результат такой

    Код (Text):
    1. ?CheckOS@@YAHXZ PROC                    ; CheckOS, COMDAT
    2. ; Line 146
    3.     sub esp, 148                ; 00000094H
    4. ; Line 150
    5.     push    148                 ; 00000094H
    6.     lea eax, DWORD PTR _osvi$[esp+152]
    7.     push    0
    8.     push    eax
    9.     call    _memset
    10.     add esp, 12                 ; 0000000cH
    11. ; Line 152
    12.     lea ecx, DWORD PTR _osvi$[esp+148]
    13.     push    ecx
    14.     mov DWORD PTR _osvi$[esp+152], 148      ; 00000094H
    15.     call    DWORD PTR __imp__GetVersionExA@4
    16.     test    eax, eax
    17.     je  SHORT $LN1@CheckOS
    18. ; Line 153
    19.     xor eax, eax
    20.     cmp DWORD PTR _osvi$[esp+164], 2
    21.     sete    al
    22. ; Line 155
    23.     add esp, 148                ; 00000094H
    24.     ret 0
    25. $LN1@CheckOS:
    26. ; Line 154
    27.     xor eax, eax
    28. ; Line 155
    29.     add esp, 148                ; 00000094H
    30.     ret 0
    31. ?CheckOS@@YAHXZ ENDP
     
  7. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Asterix
    Значит, они просто упразднили эту фичу с инлайном внешних функций (intrinsics). Жаль.
     
  8. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    кажется тут написано про что-то похожее в конце статьи, но я не знаю португальский %)
    http://www.caloni.com.br/blog/2006/05/o-que-muda-em-c-no-visual-studio-2005.html
     
  9. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Quantum
    ну не знаю, strcpy например замечательно инлайнит
     
  10. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Там написано:
     
  11. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Тогда интересен такой вопрос, кажется уже вышла бета версия SP1 для VS 2005,
    кто-нибудь уже поставил? Есть ли там положительные изменения по-поводу subj'а?
     
  12. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    S_T_A_S_ наставил меня на путь истинный %)
    я прогнал когда пробовал подсунуть линкеру свою memset
    надо было extern "C" вместо extern юзать
    и чтоб скомпилилось нужно юзать
    #pragma function(memset)

    его вариант memset

    Код (Text):
    1. #if _MSC_VER == 1400
    2.  
    3. #pragma function(memset)
    4.  
    5. extern "C"
    6. void * __cdecl
    7.   memset(void * const s,
    8.          int    c,
    9.          size_t n)
    10. {
    11.   unsigned char * const p = reinterpret_cast<unsigned char*>(s);
    12.   for ( unsigned i = 0; i != n; ++i )
    13.     p[i] = static_cast<unsigned char>(c);
    14.   return s;
    15. }
    16.  
    17. #endif
     
  13. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Точно, баг - стандартная memset ни в какую не инлайнится, несмотря на заявленную в документации #pragma intrinsic(memset).
     
  14. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    А у кого-то есть Visual Studio 2007 Orcas, что там?
     
  15. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Asterix
    По-моему чем умнее компилятор тем лучше. Чем больше ты контролируешь компилятор, тем меньше у него возможности для творчества, т. е. для оптимизации. Если надо полный контроль над кодом, тогда следует на асме писать.

    Не просто библиотеки, а CRT, которая по сути является частью компилятора.

    У меня как-то тоже была такая же проблема. В некоторых режимах оптимизации компилятор игнорировал /Oi - вставлял вызов memset, memcpy,..., считая это целесообразным для данного режима.
    И это не вовсе не баг компилятора - /Oi разрешает, а не обязывает его использовать intrinsic варианты ф-ций. Хотя опция типа "force intrinsic functions" не помешала бы...

    Попробуй разные комбинации (/O1, /O2) и (/Os, /Ot).

    И ещё на всякий случай
    Код (Text):
    1. #pragma intrinsic(memset)
    хотя это вряд ли поможет...

    В крайнем случае, чтобы избавиться от CRT, придется написать свою реализацию memset.
     
  16. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Блин, ну намудрили. Цикл с конца просто делать надо.
     
  17. minlexx

    minlexx New Member

    Публикаций:
    0
    Регистрация:
    15 мар 2009
    Сообщения:
    4
    ИМХО компилер вставляет вызов _memset когда используется обнуление буферов при инициализации

    /nodefaultlib /entry:lol: llMain
    Код (Text):
    1. BOOL WINAPI DllMain( HINSTANCE hInst,DWORD reason,LPVOID )
    2. {
    3.     if( reason == DLL_PROCESS_ATTACH )
    4.     {
    5.         hLThis = hInst;
    6.         char windir[256] = {0};
    7.         char ws2_32_path[256] = {0};
    8.         GetWindowsDirectoryA( windir, 255 );
    выдает error LNK2019: unresolved external symbol _memset referenced in function _DllMain@12
    disasm:
    Код (Text):
    1. mov     eax, [esp+200h+arg_0]
    2. push    0FFh            ; Size
    3. lea     ecx, [esp+204h+Dst]
    4. push    0               ; Val
    5. push    ecx             ; Dst
    6. mov     ds:?hLThis@@3PAUHINSTANCE__@@A, eax ; HINSTANCE__ * hLThis
    7. mov     [esp+20Ch+Buffer], 0
    8. call    _memset
    9. push    0FFh            ; Size
    10. lea     edx, [esp+210h+var_1FF]
    11. push    0               ; Val
    12. push    edx             ; Dst
    13. mov     [esp+218h+var_200], 0
    14. call    _memset
    15. add     esp, 18h
    16. push    0FFh            ; uSize
    17. lea     eax, [esp+204h+Buffer]
    18. push    eax             ; lpBuffer
    19. call    dword ptr ds:__imp__GetWindowsDirectoryA@8 ; GetWindowsDirectoryA(x,x)
    стоит поменять
    Код (Text):
    1. char windir[256] = {0};
    на
    Код (Text):
    1. char windir[256];
    2. windir[0] = 0;
    и вызов _memset пропадает
    disasm:
    Код (Text):
    1. mov     [esp+208h+var_200], 0
    2. mov     [esp+208h+Buffer], 0
    3. call    dword ptr ds:__imp__GetWindowsDirectoryA@8 ; GetWindowsDirectoryA(x,x)
    таким образом с помощью ключей линкера /NODEFAULTLIB, /ENTRY:lol: llMain, а также опций компилера /GS- (убивает вызовы _security_check_cookie) удается избавиться от CRT...

    tested in msvc2008express
     
  18. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    Asterix, попробуй static CRT и добавь /OPT:REF линкеру.
     
  19. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    кста, так если ты компилишь c /NODEFAULTLIB, то попробуй подсунуть линкеру ещё один .obj в котором будет memset()
     
  20. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    теме то уже 3 года :))))