Context: In a recent conversation, the question "does gcc/clang do strlen("static string")
at compile time?" came up. After some testing, the answer seems to be yes, regardless the level of optimization. I was a bit surprised to see this done even at -O0
, so I did some testing, and eventually arrived to the following code:
#include <stdio.h>
unsigned long strlen(const char* s) {
return 10;
}
unsigned long f() {
return strlen("abcd");
}
unsigned long g(const char* s) {
return strlen(s);
}
int main() {
printf("%ld %ld
",f(),g("abcd"));
return 0;
}
To my surprise, it prints 4 10
and not 10 10
. I tried compiling with gcc
and clang
, and with various flags (-pedantic
, -O0
, -O3
, -std=c89
, -std=c11
, ...) and the behavior is consistent between the tests.
Since I didn't include string.h
, I expected my definition of strlen
to be used. But the assembly code shows indeed that strlen("abcd")
was basically replaced by return 4
(which is what I'm observing when running the program).
Also, the compilers print no warnings with -Wall -Wextra
(more precisely, none related to the issue: they still warn that parameter s
is unused in my definition of strlen
).
Two (related) questions arise (I think they are related enough to be asked in the same question):
- is it allowed to redefine a standard function in C when the header declaring it isn't included?
- does this program behave as it should? If so, what happens exactly?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…