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.
Related
I'm trying to launch the example code from aligned alloc:
#include <cstdio>
#include <cstdlib>
int main()
{
int* p1 = static_cast<int*>(std::malloc(10*sizeof *p1));
std::printf("default-aligned address: %p\n", static_cast<void*>(p1));
std::free(p1);
int* p2 = static_cast<int*>(std::aligned_alloc(1024, 1024));
std::printf("1024-byte aligned address: %p\n", static_cast<void*>(p2));
std::free(p2);
}
My compilers give me this error:
$ g++-mp-8 main.cpp -std=c++17
main.cpp:10:38: error: no member named 'aligned_alloc' in namespace 'std'
int* p2 = static_cast<int*>(std::aligned_alloc(1024, 1024));
I am working with macOS High Sierra 10.13.6 and tried to compile this code with Macport's GCC 7.3.0, 8.2.0 and CLang (Apple LLVM version 10.0.0), they all produce the same error.
Edit: It doesn't work with either std:: present or not.
Edit2: I installed macOS Mojave and that did not fix the problem. I hoped it'll reinstall macOS's toolchain but it didn't. So I guess I cannot accept provided answers until I get a more specific one.
I am not using macOS but I have similar problems on linux using a custom g++. If you look at the cstdlib header, there is something like
#if __cplusplus >= 201703L && defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)
using ::aligned_alloc;
#endif
So aligned_alloc is only pulled into the std namespace if C++17 is available and glibcxx supports it. You can check x86_64-linux-gnu/bits/c++config.h (or something similar on macOS) if _GLIBCXX_HAVE_ALIGNED_ALLOCis defined. If not your glibc version is too old.
For clang and the libc++ implementation aligned_alloc is available if _LIBCPP_HAS_C11_FEATURES is defined which again depends on a recent version of glibc.
As an alternative you can use boost.
As the accepted answer mentions it, using boost::align::aligned_alloc solves the problem.
To fix the error without source modification, just add the following on top of the file:
#ifdef __APPLE__
#include <boost/align/aligned_alloc.hpp>
using boost::alignment::aligned_alloc;
#endif
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).
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
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
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).