I have a file which, for the sake of example, I have called 'error.c'. In this I need to include unistd.h, but I am presented with the following upon error compilation with "gcc -std=c99 -Wall -pedantic -Werror":
In file included from error.c:1:0: c:\mingw\include\unistd.h:65:20: error: unknown type name 'off_t' int ftruncate(int, off_t); ^
Versions:
$ gcc --version
gcc.exe (GCC) 4.8.1
$ ld -v
GNU ld (GNU Binutils) 2.23.2
Shell:
$ uname -a
CYGWIN_NT-6.2-WOW64 CraigsLaptop 1.7.25(0.270/5/3) 2013-08-31 20:39 i686 Cygwin
Minimum Code Required:
#include <unistd.h>
int main() {}
~~~~
Thanks for the report. There are two issues here:
You are in breach of the contract you entered into with the compiler, when you specified
-std=c99
; that option requests strict standards conformance checking, andunistd.h
is not a C99 header, so you should not be using it in a strictly conforming application.I suppose MinGW's
unistd.h
could handle this more elegantly; it should probably#error
, with a "you can't include me in a strictly conforming ISO-C translation unit" message.I'll leave it to Earnie to decide how MinGW should deal with this, but strictly, it is your bug.
Keith,
I ran into the same problem as the OP while porting an application to MinGW. Note that including
unistd.h
using-std=c99
works out of the box on various kinds of Linux systems.You are right,
unistd.h
is not a C99 header. But why should the language dialect option-std=c99
prevent you from including POSIX headers? According to POSIX, if you want to useunistd.h
, you need to define_POSIX_VERSION
,_POSIX2_VERSION
, and_XOPEN_VERSION
. But even with these required defines the compilation fails (gcc -std=c99 -D_POSIX_VERSION=200112L -D_POSIX2_VERSION=200112L -D_XOPEN_VERSION=600 error.c
). This is IMHO a bug.Language dialect and usage of POSIX functionality are IMHO orthogonal issues. Fixing this by issuing an
#error
is IMHO not the final solution if the-D_POSIX...
compilation still fails.In my porting effort the autoconf-generated configure script created lots of Header Present But Cannot Be Compiled warnings when using
-std=c99
. I just want to let you know that these warnings don't show up on Linux/AIX/BlueGene/Cray/FX10/SGI systems using gcc/intel/pgi/xl/fujitsu/oracle compilers. MinGW seems to behave differently in this respect.My workaround is to use
-std=gnu99
on MinGW only.Thanks for providing MinGW.
Christian
Being "user friendly" with this is good but doing so will set a precedence toward other such strict ansi code. I need to think more about this one.
Being "user friendly" is a double edged sword. If you are "user friendly" to users who think they should be able to use non-standard features, when they've specified
-std=c99
, then you are being hostile to those who use that for its intended purpose -- to check for standards conforming usage.IMO, strict should mean strict, and that option requests checking for strict standards conformity. It is appropriate that system headers, such as
unistd.h
, which are not specified by the standard should be prohibited, as should non-standard types such asoff_t
, when any such conformity checking option is specified.FWIW, I also consider it to be a build system bug, when any such conformity checking option is unconditionally applied to a release build; they are intended primarily for developers, to allow them to check for non-conforming usage in their code, so that it may be compiled by the widest possible range of compilers. They are not intended to create obstacles for users of more capable compilers.
I think it will be best just to guard the function with #ifndef
__STRICT_ANSI__
. ANSI doesn't prevent a header from being included regardless of its name. However a function that is not declared in the ANSI space is a different issue.Last edit: Earnie Boyd 2013-09-18
Just guard the one function? Or the entire content of the header? Since it's not an ANSI header, it seems logical that everything it declares would be out of scope, for a strictly ANSI build.
At first I had just guarded the function but you do make a valid point and I have now guarded the entire file. This begs the question what other runtime header should not be used because of
__STRICT_ANSI__
.Fixed pending release of 4.1-dev.
Keith's suggestion to emit an error if
__STRICT_ANSI__
is in use is essential to make MinGW work reliably with autoconf scripts, IMHO.If I call
AC_CHECK_HEADER
to test for the presence ofunistd.h
, I get 'yes' as the answer with MinGW. However, if I use gcc's-ansi
flag for the tests, I still get 'yes', since the header file is both present and compilable. Consequently, a snippet likefails during compilation if I set
-ansi
inCFLAGS
while running the configure script, which is more than surprising for users, I guess...