I have code that compiled happily with g++ version 3.something. I then wanted to build some other code that had C++11 symbols in it so I upgraded to g++ 4.7. Now my original code doesn't build. I get the error:
'fdopen' was not declared in this scope
According to the man page, fdopen() is declared in stdio.h which I am including. I'm not sure it is relevant, but I am working in a Cygwin environment. The exact version of g++ I am using is version 4.7.2 provided by Cygwin.
I have not changed this code since I switched compiler and I can definitely confirm that it built and my test code ran and passed with the previous compiler.
As requested, example code to demonstrate the problem:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
int fd;
FILE *fp;
fd = open("test.txt", (O_WRONLY | O_CREAT | O_EXCL), S_IRWXU);
if(0 < fd)
{
fp = fdopen(fd, "wb");
fprintf(fp, "Testing...\n");
fclose(fp);
}
return 0;
}
# g++ -std=c++11 -o test test.cpp
test.cpp: In function 'int main(int, char**)':
test.cpp:14:29: error: 'fdopen' was not declared in this scope
Whatever you do, please don't mess with the __STRICT_ANSI__
flag. That symbol is controlled by GCC. You should let GCC define it and leave it alone.
What you are really looking for is the _POSIX_C_SOURCE
feature test macro. You see, fdopen
is not defined by the C language standard. When you tell GCC that you are writing a C++11 program, then GCC goes into "strict" mode where it tries to not define any functions that are not defined by the language. This is to avoid name collisions with your own code. For instance, a valid C++11 program is free to define its own function named fdopen
since fdopen
is not a reserved identifier in the language.
But fdopen
is defined by POSIX, which is a standard that includes, but is separate from, the C language standard. When writing an application that uses POSIX functions, like fdopen
, you must tell the system that you intend to write a POSIX application so that it knows that it should make functions defined by POSIX available to your program. This is where the _POSIX_C_SOURCE
feature test macro comes in. At the top of every source file, before inclusion of any header, define this macro to the appropriate value. For instance:
#define _POSIX_C_SOURCE 200112L
The value you should use in the definition depends on which version of POSIX you are targeting. If you are unsure about which version you want to target, you can just target the same version that your host system is compliant with. You can determine this by running getconf
from a shell:
$ getconf _POSIX_VERSION
200809L
$ _
Here, my system tells me it is compliant with POSIX version 200809L
(i.e. POSIX.1-2008). I can #define _POSIX_C_SOURCE 200809L
in my source code and be confident that all standard features supported by my system will be made available to me.
The problem comes from -std=c++11
. The fdopen()
function is not in ANSI C (only in the POSIX standard), and compiling with -std=c++11
option implies defining __STRICT_ANSI__
, which excludes several functions from stdio.h
. By the way, in C++ programs, you should normally include <cstdio>
instead of <stdio.h>
, see here: stdio.h not standard in C++?.
If you need to use fdopen()
, you might want to remove the -std=c++11
option when compiling. Another possible soltion, although not really elegant, can be to use this in your source code:
#ifdef __STRICT_ANSI__
#undef __STRICT_ANSI__
#include <cstdio>
#define __STRICT_ANSI__
#else
#include <cstdio>
#endif
(which is intended to work with and without the -std=c++11
option).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With