Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo


#2046 unknown type name 'off_t'

Earnie Boyd
Craig Wale

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);

$ gcc --version
gcc.exe (GCC) 4.8.1

$ ld -v
GNU ld (GNU Binutils) 2.23.2

$ 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() {}


Issues: #2104
Issues: #2200


  • Keith Marshall
    Keith Marshall

    Thanks for the report. There are two issues here:

    1. 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, and unistd.h is not a C99 header, so you should not be using it in a strictly conforming application.

    2. 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 use unistd.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.


  • Keith Marshall
    Keith Marshall

    • status: unread --> assigned
    • assigned_to: Earnie Boyd
    • Group: OTHER --> WSL
  • Earnie Boyd
    Earnie Boyd

    • status: assigned --> pending
    • Resolution: none --> later
    • Category: Unknown --> Feature_in_WSL_4.1
  • Earnie Boyd
    Earnie Boyd

    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.

  • Keith Marshall
    Keith Marshall

    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 as off_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.

  • Earnie Boyd
    Earnie Boyd

    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
    • Keith Marshall
      Keith Marshall

      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.

      • Earnie Boyd
        Earnie Boyd

        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__.

  • Earnie Boyd
    Earnie Boyd

    • Resolution: later --> fixed
  • Earnie Boyd
    Earnie Boyd

    Fixed pending release of 4.1-dev.

  • Werner LEMBERG
    Werner LEMBERG

    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 of unistd.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 like

    #ifdef HAVE_UNISTD_H
    #  include <unistd.h>
    #include <zlib.h>
    int main(void)

    fails during compilation if I set -ansi in CFLAGS while running the configure script, which is more than surprising for users, I guess...