I installed clang-tidy on Ubuntu using:
sudo apt install clang-tidy
I ran it on a simple C++ 17 file, and got a warning and errors:
/home/erelsgl/Dropbox/ariel/CPLUSPLUS/intro/01-single-file/ptr.cpp:17:3: warning: 'auto' type specifier is a C++11 extension [clang-diagnostic-c++11-extensions]
auto i = make_unique<int>();
^
/home/erelsgl/Dropbox/ariel/CPLUSPLUS/intro/01-single-file/ptr.cpp:17:12: error: use of undeclared identifier 'make_unique' [clang-diagnostic-error]
auto i = make_unique<int>();
How can I tell clang-tidy to check this file according to c++17 standards?
NOTE: To build the program, I run:
clang++-5.0 --std=c++17 ptr.cpp
Depending on your compiler / clang-tidy version, the default C++ standard version used to compile source files may vary. clang's default std version is gnu++-98 (or gnu++-14 starting with clang 6.0), and typically clang-tidy has the same defaults as clang.
I'm guessing that -std=c++17 (or -std=c++1z) isn't specified in the C++ compiler flags, used for compiling ptr.cpp, so clang-tidy falls back to the default -std=gnu++98, and therefore gives warnings for C++11 code.
For asking clang-tidy to handle C++17, you should specify the -std flag as suggested by #n.m., as parameter to the -extra-arg option, for example:
clang-tidy -p . ptr.cpp -extra-arg=-std=c++17
Edit:
Since clang++-5.0 is used for compiling ptr.cpp, it may be a good idea to use the matching clang-tidy version, 5.0 (on Ubuntu 16.04, the default clang-tidy version installed through apt is 3.8), that is:
clang-tidy-5.0 -p . ptr.cpp -extra-arg=-std=c++17
If not already installed, you could grab it from:
https://www.ubuntuupdates.org/package/xorg-edgers/xenial/main/base/clang-tidy-5.0
Related
I have GCC 11.2.0 installed on my Windows 10 machine (from here: https://winlibs.com/). I have updated the environment variable Path to C:\MinGW\bin
gcc version 11.2.0 (MinGW-W64 x86_64-posix-seh, built by Brecht Sanders)
I'm using VSCode with the C/C++ extension configured to use the correct compiler path.
I want to use a C++20 feature which is
std::numbers::sqrt2
Still I get an error telling me it doesn't know std::numbers
[Running] cd "c:\Users\XX\XX\" && g++
main.cpp -o main && "c:\Users\XX\XX\"main
main.cpp: In function 'double sin_x_plus_cos_sqrt2_times_x(double)':
main.cpp:15:41: error: 'std::numbers' has not been declared
15 | return std::sin(x) + std::cos( std::numbers::sqrt2 * x );
|
I've added the header #include <numbers>
What am I missing ?
Default version of c++ standard for this version of gcc is C++17.
See this: https://godbolt.org/z/4Pjzd5r7s
Use
g++ main.cpp -o main -std=c++20
to force C++20
There is some support of C++20 in gcc, but it is simply to early to make it default standard.
What am I missing ?
In order to use C++20 features, you need to select the C++20 standard version.
Both gcc 10 & 11 require -std=c++20 on the command line for std::numbers to work. (Older versions than that don't support std::numbers at all)
https://gcc.gnu.org/projects/cxx-status.html#cxx20 shows progress on standards compliance. I would expect a standard to become default soon after all the details of the standard are met. As of Nov 2021, it seems they've got pretty much everything except some remaining details of the C++20 "modules" features.
I'm trying to compile the EOS blockchain/smart contract project on GitHub on Ubuntu 14.04:
https://github.com/EOSIO/eos
After getting Clang 4.0 to install, installing build_essentials, and upgrading CMake to 3.5, I was able to run the build process without any missing dependencies. However, now I get the errors shown below when I build the EOS source. This seems to me like another general issue with the configuration of the tools on my system since many people are able to compile the EOS code, although usually on Ubuntu 14.04.
Can anyone tell by looking at the errors I'm getting what tool or library I need to install or upgrade?
In file included from /usr/lib/llvm-4.0/include/clang/AST/Decl.h:31:
/usr/lib/llvm-4.0/include/llvm/Support/TrailingObjects.h:259:33: error: 'BaseTy' does not refer to a value
static_assert(LLVM_IS_FINAL(BaseTy), "BaseTy must be final.");
^
/usr/lib/llvm-4.0/include/llvm/Support/TrailingObjects.h:233:20: note: declared here
template <typename BaseTy, typename... TrailingTys>
^
/usr/lib/llvm-4.0/include/llvm/Support/TrailingObjects.h:259:19: error: expected expression
static_assert(LLVM_IS_FINAL(BaseTy), "BaseTy must be final.");
^
/usr/lib/llvm-4.0/include/llvm/Support/type_traits.h:104:45: note: expanded from macro 'LLVM_IS_FINAL'
#define LLVM_IS_FINAL(Ty) std::is_final<Ty>()
^
Linking CXX executable codegen
/home/robert/Documents/GitHub/eos/programs/launcher/main.cpp:405:18: error: no template named 'underlying_type_t' in namespace 'std'; did you mean
'underlying_type'?
using T = std::underlying_type_t <enum_type>;
~~~~~^~~~~~~~~~~~~~~~~
underlying_type
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/type_traits:1855:12: note: 'underlying_type' declared here
struct underlying_type
^
/home/robert/Documents/GitHub/eos/programs/launcher/main.cpp:435:17: error: no member named 'put_time' in namespace 'std'
dstrm << std::put_time(std::localtime(&now_c), "%Y_%m_%d_%H_%M_%S");
~~~~~^
[ 64%] Building CXX object libraries/chain/CMakeFiles/eos_chain.dir/chain_controller.cpp.o
/home/robert/Documents/GitHub/eos/programs/launcher/main.cpp:406:39: error: no matching conversion for static_cast from 'allowed_connection' to 'T'
(aka 'underlying_type<allowed_connection>')
return lhs = static_cast<enum_type>(static_cast<T>(lhs) | static_cast<T>(rhs));
^~~~~~~~~~~~~~~~~~~
The Missing _t alias names look like you’re having issues with C++14. The header paths in the error messages look like you’re using the standard library from GCC 4.8 (the default compiler on Ubuntu 14.04), which is simply too old.
I can see two solutions:
Switch from GCC’s libstdc++ to an up-to-date version of LLVM’s libc++. I’m not familiar enough with Ubuntu to tell you how to install it. For the compilation of EOSIO you must pass the -stdlib=libc++ option to Clang to switch to the different stdlib. EOSIO looks like it’s using CMake, so you have to include -DCMAKE_CXX_FLAGS=-stdlib=libc++ in your CMake command line.
Use the Toolchain test builds PPA to install a newer GCC and and libstdc++ in addition to your system’s default one. For Ubuntu 14.04 GCC 7.2.0 is the latest version available, which is perfectly C++14 capable. Add the PPA to your package sources and then do a:
sudo apt-get install gcc-7 g++-7
This installs both the GCC C compiler and C++ compiler along with the stdlib. Your default compiler is still going to be the old GCC 4.8, so you’ll have to tell CMake about the newer versions:
-DCMAKE_CXX_COMPILER=g++-7 -DCMAKE_C_COMPILER=gcc-7
Note that now you compile EOSIO with GCC (and the new stdlib) instead of Clang. Instructing Clang to use a specific version of libstdc++ should be possible, but I don’t know how.
Official support is for Ubuntu 16.10. Consider upgrading.
(EDITED: I mistakenly said 14.10)
Source: https://github.com/EOSIO/eos/wiki/Local-Environment#211-ubuntu-1610
I'm trying to get emscripten to work on OS X 10.8, see this post for some related issues there. Apparently the clang++ version shipped with Xcode is too old, so I got a recent clang 3.7.0 using MacPorts. I even told CMake to use that compiler (passing -DCMAKE_CXX_COMPILER=clang++-mp-3.7 on the command line), but it still fails:
[ 33%] Building CXX object CMakeFiles/optimizer.dir/parser.cpp.o
/opt/local/bin/clang++-mp-3.7 -std=c++11 -fno-exceptions -fno-rtti -O3 -DNDEBUG
-o CMakeFiles/optimizer.dir/parser.cpp.o
-c …/emsdk/emscripten/master/tools/optimizer/parser.cpp
In file included from …/emsdk/emscripten/master/tools/optimizer/parser.cpp:2:
In file included from …/emsdk/emscripten/master/tools/optimizer/parser.h:12:
…/emsdk/emscripten/master/tools/optimizer/istring.h:3:10: fatal error:
'unordered_set' file not found
#include <unordered_set>
^
1 error generated.
I can reproduce that issue by launching the compiler from the command line. In parallel build mode, sometimes it's instead complaining about <cstdint> for optimizer.cpp instead. Both these headers exist in /opt/local/libexec/llvm-3.7/include/c++/v1/.
What's the canonical way to use the macports-installed version of clang++ including its headers? Do I have to use -I and work out the full path, or is there something shorter?
Can I safely do so without also switching the runtime library to the one shipped with MacPorts' clang? If not, can I somehow encode the full path of the runtime library into the created binary, either for that single library or using the -rpath argument to ld or some equivalent alternative?
Update: I get unresolved symbols when I try to link stuff after specifying the include directory manually, and I don't know how to solve that. The libcxx package from MacPorts is empty except for a readme file.
I've solved the original problem by adding CXXFLAGS=--stdlib=libc++ to the environment. Then even the system version of clang will do everything I need. That flag works magic for MacPorts' version of clang as well: specifying that I get a successful build, and I can even verify (using the -E compiler switch) that it's using the headers I mentioned before. I'm still not certain whether there is anything to ensure that the headers match the system's version of libc++, though.
I have some code written using the C++11 standards, and our g++ version is 4.4.6, so as far as I can tell, C++11 should be supported (from 4.3 onwards).
However upon trying to compile with the flags -std=c++11 -std=gnu++11, I get repetitions of the errors
cc1plus: error: unrecognized command line option `-std=c++11`
cc1plus: error: unrecognized command line option `-std=gnu++11`
Compiling with -std=c++0x produces errors such as
DeviceInfo.cpp:22: error: expected initializer before ‘:’ token
corresponding to this line of code:
for (cl::Platform& plat : platforms)
Is this a C++11 specific bit of Syntax? (it doesn't look like it to me, but all this code has been given as an example so should work as provided with the compiler.)
Any help?
-std=c++11 setting is supported by much later versions of GCC. The initial support for nascent C++11 was enabled by -std=c++0x setting. This is probably what you should try.
And yes, the for syntax you are trying to use is chiefly C++11 syntax.
It appears as if range-based for loops are supported in 4.6 and newer.
This page shows GCC support for C++11 features.
for (cl::Platform& plat : platforms)
Yes, it is C++11 specific usage. GCC 4.7 or later supports C++11 with -std=c++11 option meanwhile.
I'm having the same problem described in this post except I'm using Intel version 12.1.3. (g++'s header <functional> is protected with #ifdef __GXX_EXPERIMENTAL_CXX0X__ which is not defined when icpc is used.)
Instead of using boost::functional, I wanted to install gcc4.7 and use it's std libraries.
In Ubuntu 11.10 I have gcc4.6.1 but I also installed gcc4.7 from the gcc-snapshot package.
Intel has the options -gcc-name, -gxx-name, and -cxxlib.
So originally I compiled with:
-std=c++0x -gcc-name=/usr/lib/gcc-snapshot/bin/gcc -gxx-name=/usr/lib/gcc-snapshot/bin/g++ -cxxlib=/usr/lib/gcc-snapshot/
but I get the error:
icpc: error #10282: file
'/usr/lib/gcc-snapshot/bin/usr/lib/gcc-snapshot/bin/g++' not found,
generated based on '-cxxlib=/usr/lib/gcc-snapshot/'
So then I compiled with:
-std=c++0x -gcc-name=./gcc -gxx-name=./g++ -cxxlib=/usr/lib/gcc-snapshot/.
But I still get the warnings and errors:
Warning #2928: the __GXX_EXPERIMENTAL_CXX0X__ macro is disabled when using GNU version 4.6 with the c++0x option
error: namespace "std" has no member "function"
The warning clearly says it's still using version 4.6. Does anybody know how to get Intel to use the correct libraries?
I've found that if you compile with gcc (or g++) with flags -v -Q you get a list of flags and defines. It might help you see what gcc does so maybe you can use the same -D/-U in icpc. also g++ -E will preprocess without compiling: you can get useful path information from that.