Я прочитал здесь, что компилятор может удалить вызов 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, поэтому он не выходя из собрания независимо от того, что я ожидал. Мне придется исследовать это.