GCC with -fno-builtin doesn't seem to work

I would like to compare the GCC memcpy built-in function compared to one of libc. However, all iterations of -fno-builtin or -fno-builtin-memcpy seem ignored.

 //g++ -O3 foo.cpp -S or //g++ -O3 -fno-builtin foo.cpp -S #include <string.h> int main() { volatile int n = 1000; //int n = 1000; float *x = new float[1000]; float *y = new float[1000]; memcpy(y,x,sizeof(float)*n); //__builtin_memcpy(y,x,sizeof(float)*n); } 

I found that if n in the source code is not mutable, then it is embedded in the embedded code. However, when n becomes volatile, it calls the __memcpy_chk function, which is a memcpy version with a buffer overflow check . If n is volatile, and instead I call __builtin_memcpy , then it calls memcpy .

So my conclusion is that inline code is only generated when n is known at compile time and that -fno-builtin useless. I am using GCC 4.8.2.

Is -fno-builtin deprecated? Is there a way to make a GCC memcpy call from the C library, even when n known at compile time?

+5
source share
2 answers

-fno-builtin and -fno-builtin-memcpy both expected with gcc 4.9.1. This is probably just a bug in gcc 4.8.2; this particular combination of options is not widely used. -ffreestanding is a related switch that may have the effect you want with 4.8.2.

Please note that the compiler is within its rights to optimize your program to

 int main() { return 0; } 

when called without -fno-builtin(-memcpy) or -ffreestanding , even if n is volatile , because it can (in principle) prove that the program as a whole either does not have observable side effects, or its behavior is undefined. (When n not volatile , there cannot be UB, UB occurs if n is outside the range [0, 1000] when reading, and volatile tells the compiler that it cannot assume that n has a value written to it by the program.)

+3
source

Note: since you are compiling C ++ code, I am not 100% sure if applicable.

The C standard requires that all library functions (unless explicitly stated otherwise) have an address and can be an operand of the address operator & . This is due to the fact that it allows you to implement some / most functions as a functional macro, but in some cases it should behave like an actual variable / function. To avoid the macro version, you just need something between the memcpy token and the token ( (as @Zach pointed out, the space is not enough):

 (memcpy)(y, x, ...) 

This forces you to use the actual function, which should avoid any inline macro definition.


It is also possible (reading: likely) that the -O3 optimization will scan for specific function calls (e.g. memcpy ) and replace them with inline calls, regardless of -fno-builtin .

+1
source

Source: https://habr.com/ru/post/1200155/


All Articles