I'm trying to reimplement the standard strlen function in C, and I'm closely replicating its behavior. I defined my function based on standard C declaration for strlen:
size_t ft_strlen(const char *s);
and implemented it correctly.
However, I noticed something unexpected:
Calling strlen(NULL) causes a compile-time warning:
ft_strlen.c:36:29: warning: null passed to a callee that requires a non-null argument [-Wnonnull] printf("%zu\n", strlen(0)); ~^ 1 warning generated.
Calling ft_strlen(NULL) compiles fine, but crashes at runtime with
zsh: segmentation fault (core dumped) ./a.out
Given that both functions have the exact same signature and are passed the same input and both compiled with cc, why does strlen(NULL) fail to compile, while ft_strlen(NULL) does not?
The compiler version:
Ubuntu clang version 12.0.1-19ubuntu3 Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin
I'm trying to understand the compiler-level behavior and how standard library functions differ from user-defined ones, and how can I potentially replicate strlen() myself.
One way to make ft_strlen(NULL) be stopped at compiler-time, is to add this line at the top of the code:
__attribute__((nonnull(1)))
This is an attribute, a GCC/Clang compiler-specific directive that tells the compiler "The first argument to this function must not be NULL".