I'm working with eclipse and I can choose the language standard and/or other dialect flags. When I want to work with the latest language standard, do I need to declare as shown in the image or leave the language standard blank and just define c++11, or the other way around, just define the language standard c++1y and leave the flags empty?
According to Options Controlling C Dialect -std=c++1y is just a deprecated alias to -std=c++14, not to -std=c++11. Even though Eclipse offered a proper alternative option -std=c++0x, it is also deprecated, so you better leave language standard blank and set -std=c++11 among flags.
Related
I have a c++14 project that currently targets gcc 7.2, and I am looking to backport code from a project that targets c++17. This project makes extensive use of if constexpr. gcc 7.2 supports if constexpr with the --std=c++1z flag, however it brings along all the other (at the time) experimental C++17 features.
Is there a way to enable only specific language features, in this case if constexpr, in gcc 7.2?
No it is not possible. It's all or nothing.
There is some limited level of control over language dialect in g++
https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html
If these dialects are used it can raise a warning and you can turn this warning into an error.
Another way could be to create plugins for clang-tidy or clang-query to check your C++ code base do not use any construct you don't want, but it becomes a rather large work to achieve the intended purpose.
(This question is really about the "or later"-part.)
I'm a aware of the other answers which are telling us out to activate C++11 on a target/project in cmake.
My question is really how do we express C++11 or later.
As of CMake 3.8 we have the cxx_std_11-feature which forces C++11 on compilers (-std=c++11) which even support later standards and may even default to C++14 (gcc-7) or even 17 (gcc-8, iiuc).
There is also the CXX_STANDARD-target-property, but this is not transitive and also force the exact standard and not the "or later"-option.
The only way I found until now is to require cxx_range_for (or a similar feature) which makes CMake keep the default C++-standard of the compiler if at least C++11 is supported. This is supported as of CMake 3.1.
What is the correct way to select C++11 or later of a CMake-target?
Unfortunately there's no way to ask for a range of standards in CMake.
Then only way (that I have used in the past) is to use e.g. check_cxx_compiler_flag to check for -std=c++20, -std=c++17, -std=c++14 and -std=c++11 (in that order) and use the highest with e.g. target_compile_options.
If none of the flags listed is supported, then error out.
As #Some programmer dude pointed out, only way to do so is to check for C++17, then C++14 then C++11. Looking into CMake sources itself gives interesting idea how to do it in platform-agnostic way. In here try_compile command is used with corresponding CMAKE_CXX_STANDARD passed, so CMake itself determines which compiler flag should be used. Thus to check for C++14:
try_compile(CMake_CXX14_WORKS
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_LIST_DIR}/cm_cxx14_check.cpp
CMAKE_FLAGS -DCMAKE_CXX_STANDARD=14
OUTPUT_VARIABLE OUTPUT
)
where cm_cxx14_check.cpp is dummy file with main.
This is key idea here, although full logic also checks if CMAKE_CXX_STANDARD wasn't already defined or if CMake knows CMAKE_CXX_STANDARD=17 (CMake >= 3.8). Also, CMake checks for newest standard only for GNU or Clang, but I believe it is because it is not needed in MSVC in non-library code. MSVC has always enabled the newest standard by default.
Unfortunately, here is some also a corner case with GNU 4.8: "The GNU 4.8 standard library's cstdio header is not aware that C++14 honors C11's removal of "gets" from stdio.h and results in an error"
There are cases that I want to know since which version of gcc a specific compiler flag or c++ language feature is supported so that I can write compile control preprocessors in source files or in CMakeLists.txt. For example, the compiler flag -wno-missing-field-initializers is not supported in gcc 3.4.3(an ancient version I have to use), but I want to know exactly since which version does gcc support that flag. Where can I find such instructions?
You can check specific flags using CheckCXXCompilerFlag
For example,
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG(-Wno-missing-field-initializers RESULT_OF_TEST)
Although a more portable option, across compilers, is to use CMAKE_CXX_KNOWN_FEATURES
See https://cmake.org/cmake/help/latest/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html
I am using Eclipse CDT 3.8.1 with GCC Cross Compiler 8.6.0. I know how to change the C++ standard in the project properties, but I don't know what standard is used by default.
I know the default is not C++11 and the Eclipse language support page doesn't mention C++03, so I suspect the default is C++98. However, Eclipse CDT must support C++03 because adding the compiler flag -std=c++03 doesn't cause any errors.
https://www.eclipse.org/community/eclipse_newsletter/2017/april/article3.php
What is the default standard when I create a new project?
Eclipse's parser itself doesn't have a notion of a C++ standard mode. It will recognize all the C++ features that have been implemented in its parser (which, as of writing this, is all C++98 and C++11 features, some (but not all) C++14 features, and a handful of C++17 features).
However, standard library headers often contain sections that are conditional on macros denoting the C++ standard version (e.g. #if __cplusplus >= 201103 is a common check for "C++11 or later"). To determine the value of these macros, Eclipse invokes the compiler specified in the project's toolchain to discover built-in macros. The discovered value of e.g. the __cplusplus macro will depend on what standards mode the compiler runs in for this invocation.
The flags to this compiler invocation are specified in the project properties, as you mentioned. If you don't provide a flag there, the compiler will use whatever its default mode is. I believe GCC has been using -std=c++14 as the default from GCC 6 onwards. (Though I don't quite know what "GCC Cross Compiler 8.6.0" is. According to the GCC website, the latest version is 8.1.)
What are the differences between -std=c++11 and -std=gnu++11 as compilation parameter for gcc and clang? Same question with c99 and gnu99? I know about C++ and C standards, it's the differences in the parameters that interest me.
I've read somewhere that it has to do with some extensions but it is not clear to me which ones and how to choose between one or the other for a new project.
As you have found out yourself, the difference between the two options is whether GNU extensions that violates/extend the C++ standard are enabled or not. The GNU C++ extensions are described here. You can also use most of the GNU C extensions (described here) in your C++ programs. It would be also useful to read about the -Wpedantic GCC option here.
Note that some extensions can still be in effect when using -std=c++11, as long as they do not contradict the standard. For instance, when using the MinGW compiler, I need the extensions for a working Boost.Lexical_Cast. But, as long as you don't use any of them, you are better off sticking to the standard without extensions for maximum portability. This might come in handy if you find yourself forced to change compiler.