mkstemp() and fdopen() in Cygwin 1.7.28

When compiling with g++ 4.8.2 on Cygwin, I logged the expansion of macros in three cases:

$ g++ -std=c++11 -E -Dd foo.cpp > foo.log.c++11
$ g++ -ansi -E -Dd foo.cpp > foo.log.ansi
$ g++ -E -Dd foo.cpp > foo.log.noFlag

Comparing the logs was useful. There were "holes" in the -std=c++11 and -ansi cases, while a block containing the mkstemp() declaration shows up in the "flagless" case. This let me zero in on the parts of the headers that were processed differently.

In the file /usr/include/stdlib.h, declarations of mkstemp() and some other functions are rejected if __STRICT_ANSI__ is defined — such as when we use the compile-time flags -ansi and -std=c++11.

Likewise, in the file /usr/include/stdio.h, declarations of fdopen() will get skipped for the same reason.

The C++ headers <cstdlib> and <cstdio> both include the stdlib.h and stdio.h headers and leave declaration of those two functions (among others) up to those two headers. So if we use -ansi and/or -std=c++11 then those two functions will not be declared and we get the compile errors.

The solution that seems to work for the toy code samples is to undefine __STRICT_ANSI__ before compiling:

$ g++ -std=c++11 -U__STRICT_ANSI__ foo.cpp

It's not clear what the side effects of this will be, but from googling, it seems like this is a common problem and a common fix applied by other developers who need to target Cygwin.


Cygwin has a Linux-like set of Feature Test Macros. However, on Linux with C++, _GNU_SOURCE is defined unconditionally, essentially negating all such guards. On Cygwin, we do not do this, meaning you actually have to respect the meaning of the various flags on C++ as well.

As noted, using any -std=c++* flag will define __STRICT_ANSI__, which is recognized by the macros. Undefining that on the command line is incorrect. Instead, either define the correct documented flag(s) for the functions you wish to use (in this case, -D_POSIX_C_SOURCE=200809L should cover both), or use -std=gnu++* flags instead (which, btw, do not define _GNU_SOURCE) to not declare ANSI compliance.

Tags:

C++

C

Cygwin

Gcc