Search code examples
cgccgnuc89

Why does strerror_r behave differently when compiled with gnu90 and c90 standards?


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?


Solution

  • 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 #ifdefs. The -std option changes the set of pre-defined macros affecting the visibility of the prototype.