Проблема компиляции в VS 2005 такой код: Код (Text): void _test(void* dest, unsigned long len) { while (len--) { *(char *)dest = '\0'; dest = (char *)dest + 1; } } int CheckOS() { OSVERSIONINFO osvi; _test(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if ( GetVersionEx(&osvi) ) return osvi.dwPlatformId == VER_PLATFORM_WIN32_NT; return 0; } в опциях проекта установлен ключ линкеру /NODEFAULTLIB но линкер ругается error LNK2001: unresolved external symbol _memset Как заставить компилятор забыть про crt совсем и не быть таким умным заменяя мою функцию на memset Код (Text): PUBLIC ?_test@@YAXPAXK@Z ; _test EXTRN _memset:PROC ; Function compile flags: /Ogtpy ; COMDAT ?_test@@YAXPAXK@Z _TEXT SEGMENT ?_test@@YAXPAXK@Z PROC ; _test, COMDAT ; _dest$ = eax ; Line 124 push 148 ; 00000094H push 0 push eax call _memset add esp, 12 ; 0000000cH ; Line 127 ret 0 ?_test@@YAXPAXK@Z ENDP ; _test компилируется с ключами Код (Text): /O2 /Ob2 /GL /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_WINDLL" /FD /EHsc /MT /Zp1 /GS- /J /FA /Fa"Release\\" /Fo"Release\\" /Fd"Release\vc80.pdb" /W3 /nologo /c /Zi /TP /errorReport:prompt
вот в мсдн написано Код (Text): Option Equivalent to Comment /O1 (Minimize Size) /Og /Os /Oy /Ob2 /Gs /GF /Gy Creates the smallest code in the majority of cases. /O2 (Maximize Speed) /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy Creates the fastest code in the majority of cases. (default setting for release builds)
изначально я вобще хотел использовать OSVERSIONINFO osvi = {0}; и компилятор 6-й студии заменил бы этот код циклом, а вот 2005 сильно умный
Quantum Так это именно баг? Странный какой-то баг, в чём проблема с встраиванием таких примитивов? В их агрессивной оптимизации? Ну ладно, не может memset заинлайнить. Но вот чтоб думать за разработчика, заменяя его код вызовами существующих функций библиотеки — это уж черезчур. 7.1 такой фигнёй не страдает.
А по каким признакам компилятор догадывается, что _test - это аналог memset? Может сделать другой алгоритм обнуления, чтобы сбить с толку компилятор?
IceStudent Не танго танцевать, а по рукам дать ему. Поэтому и нужно определить, откуда у него эти руки растут
Asterix Мне просто интересно. Может, эта эвристика с memset выполняется компилятором после препроцессора intrinsic'ов и инлайнов. Поэтому /Oi не работает. IceStudent В MS это называют особенностью, хотя я лично не могу понять, почему они связывают это с x64 и дровами режима ядра.
это не Каспер чтобы пытаться спрятать от компилятора узнаваемый им код путем манипуляций с кодом, понятно что код можно переписать, но это танцы с бубном, в идеале желательно повлиять на компилятор с помощью ключей компиляции
Может быть это встроенная и неотключаемая ключами "фишка"? Вполне в духе МС: чтобы не лезли на уровень ниже crt.
такой код тоже не катит Код (Text): void _test(void* dest, unsigned long len) { for (unsigned long i = 0; i < len; i++) { *((char *)dest + i) = '\0'; } }
Код (Text): void _test(void* dest, unsigned long len) { for (unsigned long i = 0; i < len; i++) { *((char *)dest + i) &= '\0'; } } А так пробовал?
Наверняка компилятор реагирует на константу (0). И считает что тут нужен memset. А если поксорить каждый байт сам на себя? Явной константы нет. Или вычесть самого из себя. *((char *)dest + i) = *((char *)dest + i) ^ *((char *)dest + i);