3

The following code compiles fine:

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

extern int errno ;

int main ( void )
{
    FILE *fp;
    int errnum;
    fp = fopen ("testFile.txt", "rb");

    if ( fp == NULL )
    {
        errnum = errno;
        fprintf( stderr, "Value of errno: %d\n", errno );
        perror( "Error printed by perror" );
        fprintf( stderr, "Error opening file: %s\n", strerror( errnum ) );
        exit( 1 );
    }

    fclose ( fp );
}

But I can not compile it with:

gcc-8 -Wall -Wextra -Werror -Wstrict-prototypes

I get the following:

 program.c:6:1: error: function declaration isn’t a prototype [-Werror=strict-prototypes]
 extern int errno ;
 ^~~~~~
cc1: all warnings being treated as errors

How can I avoid/fix this? I need this compiler flag -Wstrict-prototypes

melpomene
  • 84,125
  • 8
  • 85
  • 148
Michi
  • 5,175
  • 7
  • 33
  • 58
  • 4
    You should *never* declare `errno` yourself. It doesn't *have* to be a variable (it could be a macro that calls a function, which is very common). – Some programmer dude Jul 07 '18 at 11:25

1 Answers1

7
extern int errno ;

is wrong. You should simply remove this line.

What's going on is that you're including <errno.h>, which defines a macro called errno. Well, actually ...

It is unspecified whether errno is a macro or an identifier declared with external linkage. If a macro definition is suppressed in order to access an actual object, or a program defines an identifier with the name errno, the behavior is undefined.

(That's from C99, 7.5 Errors <errno.h>.)

In your case errno probably expands to something like (*__errno()), so your declaration becomes

extern int (*__errno());

which declares __errno as a function (with an unspecified parameter list) returning a pointer to int.

melpomene
  • 84,125
  • 8
  • 85
  • 148
  • Well you are right, and the manual says: **Do not do this** ===>> `On some ancient systems, was not present or did not declare errno, so that it was necessary to declare errno man‐ ually (i.e., extern int errno). Do not do this. It long ago ceased to be necessary, and it will cause problems with mod‐ ern versions of the C library.` You can add this to your Answer if you want to. – Michi Jul 07 '18 at 11:40
  • By the way, you was right , this compiles fine ==>> `extern int (*__errno(void));` (I will not use it) which makes your Answer to be True. – Michi Jul 07 '18 at 11:45