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
Related
I want to use std::source_location in Qt Creator, I've built the GCC 11.1 and checked it using g++ main.cpp -std=c++20 that it works. I've created a kit in Qt Creator to use this compiler and I was able to build it by adding:
QMAKE_CXXFLAGS += -std=c++2a
It works and I can even debug it without issues but Qt keeps saying that I have an error (which is not an error because the build passes):
error: no type named 'source_location' in namespace 'std'
Is there something I can do to fix this?
It's all about clang's static analysis. The gcc's (or strictly libstdc++'s) header <source_location> contains following guard:
#if __cplusplus > 201703L && __has_builtin(__builtin_source_location)
The guard doesn't allow clang to work as it doesn't support __builtin_source_location. Please follow the clang PR that fixes this issue.
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.
I am trying to test the version of libstdc++ because std::regex is implemented, but largely broken, in the versions of libstdc++ distributed with GCC before version 4.9.0.
Note that:
I need to test the version of libstdc++, not GCC because Clang also supports using libstdc++ as the standard library. This rules out testing the __GNUC_PATCHLEVEL__, __GNUC__, and __GNUC_MINOR__ macros.
The __GLIBCXX__ macro is a date, not a version number and does not increase monotonically. For example, GCC 4.8.4 ships with #define __GLIBCXX__ 20150426, which is newer than the release date of GCC 4.9.0.
Is there any portable way to test the version of libstdc++ that does not depend on using GCC my compiler?
In my opinion the problem is sufficiently small to be solved by brute force.
In a header file called machine.hpp or similar I would test that the version of the C++ Standard is at least what I need it to be (the __cplusplus macro). Then I would add the various macro checks to reject any library that I know to be flawed.
In other words, I would take a black-list approach instead of a white-list approach.
For example:
#pragma once
#ifndef MACHINE_HPP_HEADER_GUARDS
#define MACHINE_HPP_HEADER_GUARDS
#if __cplusplus < 201103L
// Library is incompatible if it does not implement at least the C++11
// standard.
#error "I need a library that supports at least C++11."
#else
// Load an arbitrary header to ensure that the pre-processor macro is
// defined. Otherwise you will need to load this header AFTER you
// #include the header you care about.
#include <iosfwd>
#endif
#if __GLIBCXX__ == 20150422
#error "This version of GLIBCXX (20150422) has flaws in it"
#endif
// ...repeat for other versions of GLIBCXX that you know to be flawed
#endif // MACHINE_HPP_HEADER_GUARDS
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'm trying to determine if C++0x features are available when compiling. Is there a common preprocessor macro? I'm using Visual Studio 2010's compiler and Intel's compiler.
The macro __cplusplus will have a value greater than 199711L.
That said, not all compilers will fill this value out. Better to use Roger's solution.
The usual way to do this is determine it in the build system, and pass "configuration macros", commonly named HAS_*, when compiling. For example: compiler -DHAS_LAMBDA source.cpp.
If you can determine this from compiler version macro, then you can define these macros in a configuration header which checks that; however, you won't be able to do this for anything controlled by a command-line option. Your build system does know what options you specify, however, and can use that info.
See boost.config for a real example and lots of details about specific compilers, versions, and features.
We've had similar problems with nullptr and auto_ptr. Here's what we're trying to use until somehing is standardized:
#include <cstddef>
...
// GCC: compile with -std=c++0x
#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || (__GNUC__ >= 5))
# define HACK_GCC_ITS_CPP0X 1
#endif
#if defined(nullptr_t) || (__cplusplus > 199711L) || defined(HACK_GCC_ITS_CPP0X)
# include <memory>
using std::unique_ptr;
# define THE_AUTO_PTR unique_ptr
#else
# include <memory>
using std::auto_ptr;
# define THE_AUTO_PTR auto_ptr
#endif
It works well on GCC and Microsoft's Visual Studio. By the way, nullptr is a keyword and can't be tested - hence the reason for the nullptr_t test.