Here is my program.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
int main()
{
char errbuf[256];
errno = 0;
strtoul("99999999999999999999999999999999999999999999", NULL, 0);
strerror_r(errno, errbuf, sizeof errbuf);
printf("strerror_r: %s\n", errbuf);
return 0;
}
When I compile it with -std=gnu90
or -std=gnu99
, I get the expected output.
susam@nifty:~/lab/linux$ rm -f a.out && gcc -std=gnu90 -Wall -Wextra -pedantic foo.c && ./a.out
strerror_r: Numerical result out of range
susam@nifty:~/lab/linux$ rm -f a.out && gcc -std=gnu99 -Wall -Wextra -pedantic foo.c && ./a.out
strerror_r: Numerical result out of range
But when I compile it with -std=c90
or -std=c99
, I get a warning and I don't see strerror_r
putting the string in errbuf
.
lone@debian:~/lab/linux$ rm -f a.out && gcc -std=c90 -Wall -Wextra -pedantic foo.c && ./a.out
foo.c: In function ‘main’:
foo.c:12:2: warning: implicit declaration of function ‘strerror_r’ [-Wimplicit-function-declaration]
strerror_r(errno, errbuf, sizeof errbuf);
^
strerror_r:
lone@debian:~/lab/linux$ rm -f a.out && gcc -std=c99 -Wall -Wextra -pedantic foo.c && ./a.out
foo.c: In function ‘main’:
foo.c:12:2: warning: implicit declaration of function ‘strerror_r’ [-Wimplicit-function-declaration]
strerror_r(errno, errbuf, sizeof errbuf);
^
strerror_r:
What is going wrong when I use -std=c90
or -std=c99
?
With -std=c89
you ask the implementation to provide exclusively the declarations for identifiers part of ISO 9899:1989. The identifier strerror_r
is not part of C89 (or C99), so there is no prototype. In consequence you get the warning about an implicit declaration.
If you look at the relevant header you will likely find the strerror_r prototype buried in a maze of #ifdef
s. The -std
option changes the set of pre-defined macros affecting the visibility of the prototype.