Clang >= 3.3 in c++1y mode cannot parse <cstdio> header - c++

I have a project that correctly compiles and runs under g++ 4.8.1 and clang >= 3.3 in c++11 mode. However, when I switch to the experimental -std=c++1y mode, clang 3.3 (but not g++) chokes on the <cstdio> header that is indirectly included by way of Boost.Test (so I cannot easily change it myself)
// /usr/include/c++/4.8/cstdio
#include <stdio.h>
// Get rid of those macros defined in <stdio.h> in lieu of real functions.
// ...
#undef gets
// ...
namespace std
{
// ...
using ::gets; // <-- error with clang++ -std=c++1y
// ...
}
with the following error message:
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/cstdio:119:11:
error: no member named 'gets' in the global namespace
On this tutorial on how to set up a modern C++ environment, a similar lookup problem with max_align_t is encountered. The recommendation there is to use a sed script to surround the unknown symbols with #ifdef __clang__ macros, but that seems a fragile approach.
Setup: plain 64-bit Linux Mint 15 with
g++ (Ubuntu 4.8.1-2ubuntu1~13.04) 4.8.1
Ubuntu clang version 3.3-3~raring1 (branches/release_33) (based on
LLVM 3.3)
Questions:
what is causing this erorr? There is no __clang__ macro anywhere near the code in question, and clang in c++11 mode has no trouble at all.
Is it a language problem (does C++14 say something else than C++11 about importing C compatible symbols from the global into the std namespace)?
Do I need to change something with my include paths? (I use CMake to automatically select the header paths, and switch modes inside CMakeLists.txt)
Does clang have a switch to resolve this?

This note in the gets manpage looks relevant:
ISO C11 removes the specification of gets() from the C language, and since version 2.16, glibc header files don't expose the function declaration if the _ISOC11_SOURCE feature test macro is defined.
Probably should be
#if !_ISOC11_SOURCE
using ::gets;
#endif

Related

Mac c++ filesystem library not recognized

NOTE: this does not fail to #include <filesystem>. It fails afterward.
I’m on a macOS 10.15, using clang 11. Output of clang --version:
Apple clang version 11.0.0 (clang-1100.0.33.17)
Target: x86_64-apple-darwin19.4.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
When I try to compile something simple like:
#include <filesystem>
using namespace std;
filesystem::path dev_dir;
int main() {
dev_dir = "/dev/";
return 0;
}
The compiler does find the filesystem library, but doesn’t recognize the namespace:
$clang trigger_controller.cpp -o trigger_controller
trigger_controller.cpp:##:##: error: use of undeclared identifier 'filesystem'
filesystem::path dev_dir;
This is the file I believe I’m trying to include (which I’ve confirmed exists):
// /usr/local/include/c++/9.2.0/filesystem
#ifndef _GLIBCXX_FILESYSTEM
#define _GLIBCXX_FILESYSTEM 1
#pragma GCC system_header
#if __cplusplus >= 201703L
#include <bits/fs_fwd.h>
#include <bits/fs_path.h>
#include <bits/fs_dir.h>
#include <bits/fs_ops.h>
#define __cpp_lib_filesystem 201703
#endif // C++17
#endif // _GLIBCXX_FILESYSTEM
What am I doing wrong? Are there specific compiler options I need? Is the namespace wrong?
Yes, there are specific compiler options you need. Notice that the entire contents of this header, apart from boilerplate, are wrapped in an #if __cplusplus >= 201703L ... #endif block. That means the header is effectively empty unless the compiler declares conformance with the 2017 revision of the C++ standard (or later).
For clang and gcc, standards conformance level is controlled with the command line option -std. GCC's documentation for this option is here; I don't know where to find clang's documentation, but clang generally tries to be command-line compatible with gcc, so the same options should work.
In this case, the exact option you should use is -std=gnu++17 for C++ 2017. As of this writing, support for newer revisions of the C++ standard is still "experimental" and "will almost certainly change in incompatible ways", so I would avoid it. I also recommend you avoid the hyperconformant variant of this mode, -std=c++17, because it has a good chance of exposing bugs in MacOS system headers.

Include library from different standard [duplicate]

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

WARNING: disabled use of C++11 features in Armadillo

I am using Armadillo under windows and cygwin.
Despite, Armadillo is suggesting Mingw, Boost is suggesting cygwin and avoid using mingw. So, when I compile, I receive such warning. Is there anyway to fix this warning without hacking the soruce code of Armadillo?
The location of warning in the source code is here.
main.cpp
#include <armadillo>
int main()
{
arma::mat A(5,10);
A.ones();
return 0;
}
compile:
g++ main.cpp -std=c++11
warning:
E:\test\temp>make
g++ main.cpp -std=c++11 -fdiagnostics-color=always
In file included from /usr/include/armadillo:50:0,
from main.cpp:1:
/usr/include/armadillo_bits/compiler_setup.hpp:72:123: note: #pragma message: WA
RNING: disabled use of C++11 features in Armadillo, due to incomplete support fo
r C++11 by Cygwin
#pragma message ("WARNING: disabled use of C++11 features in Armadillo, due
to incomplete support for C++11 by Cygwin")
^
It may be a recent addition to Armadillo, but the following compile-time flag seems to do the trick:
g++ main.cpp -std=c++11 -DARMA_DONT_PRINT_CXX11_WARNING
I didn't program using Armadillo. But judging from Armadillo source code #https://github.com/conradsnicta/armadillo-code/, it seems that for all versions of Armadillo(6.1-6.5), C++11 is disabled for Cygwin.
Latest Cygwin includes GCC-5.2 and Cygwin-Gcc-4.9.2 (as well as Mingw #Cygwin) which should, IMHO, inherently support latest C++11 features.
Your best option is to delete the code block #compiler_Setup.hpp
#if defined(__CYGWIN__)
#if defined(ARMA_USE_CXX11)
#undef ARMA_USE_CXX11
#undef ARMA_USE_EXTERN_CXX11_RNG
#pragma message ("WARNING: disabled use of C++11 features in Armadillo, due to incomplete support for C++11 by Cygwin")
#endif
#endif
If that's not an option, you have to redefine ARMA_USE_CXX11 and ARMA_USE_EXTERN_CXX11_RNG.
#if defined(__GNUC__)
#if (__GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 8)))
#define ARMA_USE_CXX11
#define ARMA_USE_EXTERN_CXX11_RNG
#endif
#endif
You can define it at#RcppArmadilloForward.h after the code #include <armadillo>
Armadillo library identifies your compiler name with the help of predefined macros in the Cygwin compiler. You can #undef the __CYGWIN__ macro in your code before including the library. There may be a issue if the compiler macro is undefined because this macro can be necessary in high-performance code that aims at using the best performance tricks available for each compiler

how to enable __BEGIN_NAMESPACE_STD in stdlib.h

I am now trying to build a c++ library in linux with cmake. If I do not enable -std=c++0x option, I always get compilation errors error: 'div_t' was not declared in this scope for the following codes:
int xPos;
div_t divResult;
divResult = div(xPos,8);
Then if I enable -std-c++0x options with cmake: set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x", then everything is fine. However, in my library I did not use any c++0x features, so I am reluctant to set std=c++0x option. So I search the head file that defines div_t and find it is defined in stdlib.h within the following MACRO:
__BEGIN_NAMESPACE_STD
typedef struct
{
int quot;
int rem;
} div_t;
....
....
__END_NAMESPACE_STD
It seems to me that if I can enable these macros I can build the library without enabling c++0x feature. So my question is what I can do in this situation.
By the way, I can build the library very well without enabling c++0x feature if only g++4.4 is installed in the linux machine. When I also install g++4.6 and make g++4.6 the default g++, then the compilation error began to occur. Even I changed the default g++ to g++4.4, the compilation error still exists if I do not enable c++0x feature.
The macros expand to namespace std { and } respectively if the code is pulled in through a C++ standard library header. This leads me to believe that you're not #including stdlib.h directly (which is good!).
Earlier versions of libstdc++ pulled symbols from C legacy headers into the global namespace even if the C++ versions of these headers (e.g. <cstdlib> instead of <stdlib.h>) were used; newer ones place them only in namespace std.
The cleanest way to fix this is to
#include <cstdlib>
in all translation units where the problem occurs and to use std::div instead of div. If you're lazy, you can also
#include <stdlib.h>
in all translation units that use div, but mixing C and C++ is always icky. Not terribad in this particular case, though.

Error "'fdopen' was not declared" found with g++ 4 that compiled with g++3

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