Я прочитал здесь, что компилятор может удалить вызов memset
, если он знает, что переданный буфер памяти больше никогда не используется. Как это возможно? Мне кажется, что (с точки зрения основного языка) memset
- это просто регулярная функция, и компилятор не имеет права предполагать, что все, что происходит внутри него, не будет иметь побочных эффектов.
В связанной статье они показывают, как Visual С++ 10 удалил memset
. Я знаю, что компиляторы Microsoft не ведут стандартное соответствие, поэтому я спрашиваю - это в соответствии со стандартом, или это просто msvc-ism? Если это соответствует стандарту, пожалуйста, уточните;)
EDIT: @Cubbi
Следующий код:
void testIt(){
char foo[1234];
for (int i=0; i<1233; i++){
foo[i] = rand()%('Z'-'A'+1)+'A';
}
foo[1233]=0;
printf(foo);
memset(foo, 0, 1234);
}
Скомпилирован под mingw с линиями:
g++ -c -O2 -frtti -fexceptions -mthreads -Wall -DUNICODE -o main.o main.cpp
g++ -Wl,-s -Wl,-subsystem,console -mthreads -o main.exe main.o
objdump -d -M intel -S main.exe > dump.asm
Вывести вывод:
4013b0: 55 push ebp
4013b1: 89 e5 mov ebp,esp
4013b3: 57 push edi
4013b4: 56 push esi
4013b5: 53 push ebx
4013b6: 81 ec fc 04 00 00 sub esp,0x4fc
4013bc: 31 db xor ebx,ebx
4013be: 8d b5 16 fb ff ff lea esi,[ebp-0x4ea]
4013c4: bf 1a 00 00 00 mov edi,0x1a
4013c9: 8d 76 00 lea esi,[esi+0x0]
4013cc: e8 6f 02 00 00 call 0x401640
4013d1: 99 cdq
4013d2: f7 ff idiv edi
4013d4: 83 c2 41 add edx,0x41
4013d7: 88 14 1e mov BYTE PTR [esi+ebx*1],dl
4013da: 43 inc ebx
4013db: 81 fb d1 04 00 00 cmp ebx,0x4d1
4013e1: 75 e9 jne 0x4013cc
4013e3: c6 45 e7 00 mov BYTE PTR [ebp-0x19],0x0
4013e7: 89 34 24 mov DWORD PTR [esp],esi
4013ea: e8 59 02 00 00 call 0x401648
4013ef: 81 c4 fc 04 00 00 add esp,0x4fc
4013f5: 5b pop ebx
4013f6: 5e pop esi
4013f7: 5f pop edi
4013f8: c9 leave
4013f9: c3 ret
В строке 4013ea есть вызов memset, поэтому mingw не удалил его. Поскольку mingw на самом деле является GCC в окнах, я полагаю, что GCC делает то же самое - я проверю его при перезагрузке в linux.
По-прежнему возникают проблемы с поиском такого компилятора?
EDIT2:
Я только что узнал о GCC __attribute__ ((pure))
. Так что не то, что компилятор знает что-то особенное о memset и elides он, это просто, что он разрешил в нем заголовок - там, где его следует использовать программист;) My mingw не имеет этого атрибута в объявлении memset
, поэтому он не выходя из собрания независимо от того, что я ожидал. Мне придется исследовать это.