Reputation: 11
I'm compiling this code with -O3 -x c -std=c99 -fno-builtin -nostdlib -ffreestanding
unsigned char *memset(unsigned char *dest, unsigned char val, int count)
{
unsigned char* p = dest;
while (count--)
*p++ = val;
return dest;
}
#include <stdio.h>
int main()
{
unsigned char c[20];
memset(c, 'a', 19);
c[19] = '\0';
printf((const char*) c);
}
and using godbolt to examine what memset
gcc is calling in the assembly output.
memset:
test edx, edx
je .L6
sub edx, 1
sub rsp, 8
movzx esi, sil
add rdx, 1
call memset
add rsp, 8
ret
.L6:
mov rax, rdi
ret
main:
sub rsp, 40
movabs rax, 7016996765293437281
mov QWORD PTR [rsp], rax
mov QWORD PTR [rsp+8], rax
mov eax, 24929
mov WORD PTR [rsp+16], ax
mov rdi, rsp
xor eax, eax
mov BYTE PTR [rsp+18], 97
mov BYTE PTR [rsp+19], 0
call printf
add rsp, 40
ret
With the flags I used I'm attempting to eliminate all possibility of it calling a built-in memset
and judging from the colorization godbolt uses, it looks like gcc is doing a recursive call at *p++ = val;
. So is it doing recursion or calling builtin memset
?
Upvotes: 1
Views: 281
Reputation: 14057
As others have indicated, the setting of the array c elements has been inlined. As a result, the memset() you implemented is not even getting called. This is a result of the use of the -03 compiler option. The compiler is being very aggressive in its optimizations. Furthermore, there is no recursion on the execution path.
However, that does not entirely answer your question. The memset() shown in the disassembled output is indeed NOT the built in version and it is not even being executed.
Incidentally, you do not need to apply the -fno-builtin flag as the -ffreestanding flag automatically implies it. Also, if you enable garbage collection, I am sure that will find that the memset() routine in the disassembled output will vanish.
Upvotes: 1