I'm aware that C++20 is not fully supported (yet) by the compilers, but I really want to learn modules and other C++20 stuff.
Modules are supported in GCC11 and Clang-8+.
Compiler Support of C++20
I've installed Clang-10 on my Ubuntu, but it still gives me errors:
import <iostream>;
using namespace std;
int main(){
cout << "Hello world";
}
What am I doing wrong?
COMMANDS:
clang++ -Wall -std=c++2a -stdlib=libc++ -fimplicit-modules
-fimplicit-module-maps main.cpp -o main
clang++ -Wall -std=c++20 -stdlib=libc++ -fimplicit-modules
-fimplicit-module-maps main.cpp -o main
ERROR: fatal error: 'iostream' file not found
Although c++20 adds modules the c++20 standard library doesn't expose any modules.
Microsoft have implemented some standard library modules which may or may not match a future c++ standard: https://learn.microsoft.com/en-us/cpp/cpp/modules-cpp?view=msvc-160#consume-the-c-standard-library-as-modules. With these your example would be:
import std.core;
using namespace std;
int main(){
cout << "Hello world";
}
As far as I can see neither libc++ or libstdc++ have implemented any modules yet.
By default, gcc trunk use c++17, and clang trunk use c++14, so you have to say compiler, that you want to use c++20
If you are compiling your code in terminal by yourself, than add following flag
--std=c++2a
If you compile your code using Cmake, than add following to your CMakeLists.txt
set(CMAKE_CXX_STANDARD 20)
And if you compile in some IDE(Codeblocks or Visual studio), than somewhere in compiler settings put supporting c++20
trunk means "the main line of development", so this compiler version should be latest officially supported
Related
I am using Atom as my IDE, my current __cplusplus = 201402 which is C++14 and my compiler is g++ (GCC) 9.2.0.
How do I upgrade to C++17 or C++20?
Everything I've searched up involves using another IDE (Microsoft Visual Studio).
You don't "upgrade" to newer C++ standards.
You can upgrade compiler to newer version supporting latest standards.
As of today, most compilers are set to C++14 by default.
To change it you need to pass additional argument during compilation.
For example, to compile hello.cpp with GCC for C++17 you need to execute
g++ -std=c++17 hello.cpp
You need to check how to pass compiler flags (or set standards) in your IDE / editor / build system.
I'm not familiar with Atom, but I've found this:
In the settings, click on Packages, then search for gpp-compiler. You should see a settings button – click on it and edit the command line options to suit your needs.
Do-it-yourself:
#include <iostream>
int main(void) {
std::cout << __cplusplus;
return 0;
}
Compile this firstly with the following command:
$ g++ -o main main.cpp && ./main
Thereafter:
g++ -o main main.cpp -std=c++17 && ./main
You'll get to know the differences. Note that if you're unable to use -std=c++20 flag, it clearly means that your compiler doesn't supports C++20 standard.
I wanted to compile C++11 source code within Mac Terminal but failed. I tried g++ -std=c++11, g++ -std=c++0x, g++ -std=gnu++11 and g++ -std=gnu++0x but nothing worked. Terminal always read unrecognized command line option. However, g++ -std=gnu and things like that worked fine (of course C++11 source code could not pass).
Which option should I use to turn on C++11 support?
By the way, the command line tool I'm using is installed within Xcode, and I'm pretty sure that they are up-to-date.
As others have pointed out you should use clang++ rather than g++. Also, you should use the libc++ library instead of the default libstdc++; The included version of libstdc++ is quite old and therefore does not include C++11 library features.
clang++ -std=c++11 -stdlib=libc++ -Weverything main.cpp
If you haven't installed the command line tools for Xcode you can run the compiler and other tools without doing that by using the xcrun tool.
xcrun clang++ -std=c++11 -stdlib=libc++ -Weverything main.cpp
Also if there's a particular warning you want to disable you can pass additional flags to the compiler to do so. At the end of the warning messages it shows you the most specific flag that would enable the warning. To disable that warning you prepend no- to the warning name.
For example you probably don't want the c++98 compatibility warnings. At the end of those warnings it shows the flag -Wc++98-compat and to disable them you pass -Wno-c++98-compat.
XCode uses clang and clang++ when compiling, not g++ (assuming you haven't customized things). Instead, try:
$ cat t.cpp
#include <iostream>
int main()
{
int* p = nullptr;
std::cout << p << std::endl;
}
$ clang++ -std=c++11 -stdlib=libc++ t.cpp
$ ./a.out
0x0
Thanks to bames53's answer for pointing out that I had left out -stdlib=libc++.
If you want to use some GNU extensions (and also use C++11), you can use -std=gnu++11 instead of -std=c++11, which will turn on C++11 mode and also keep GNU extensions enabled.
My code:
#include <iostream>
#include <string>
int main()
{
std::string test = "45";
int myint = std::stoi(test);
std::cout << myint << '\n';
}
Gives me the compile error:
error: 'stoi' is not a member of 'std'
int myint = std::stoi(test);
^
However, according to here, this code should compile fine. I am using the line set(CMAKE_CXX_FLAGS "-std=c++11 -O3") in my CMakeLists.txt file.
Why is it not compiling?
Update: I am using gcc, and running gcc --version prints out:
gcc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010
In libstdc++, the definitions of stoi, stol, etc., as well as the to_string functions, are guarded by the condition
#if ((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
&& !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
I have had this fail on one platform before (namely Termux on Android), resulting in to_string not being available even with g++ 6.1 and the C++14 standard. In that case, I just did
#define _GLIBCXX_USE_C99 1
before including anything, and voilà, suddenly the functions existed. (You should put this first, or even on the command line, rather than just before including <string>, because another header may include <string> first, and then its include guards will keep it from ever seeing your macro.)
I did not investigate why this macro wasn't set in the first place. Obviously this is a cause for concern if you want your code to actually work (in my case I didn't particularly, but FWIW there were no problems.)
You should check if _GLIBCXX_USE_C99 is not defined, or if _GLIBCXX_HAVE_BROKEN_VSWPRINTF is defined (which may be the case on MinGW?)
std::stoi is a C++11 function. You have to use the -std=c++11 to enable it in both g++ and clang++. This is the actual issue, not a linking error or a specific preprocessor define.
$ cat test.cxx
#include <iostream>
#include <string>
int main()
{
std::string test = "45";
int myint = std::stoi(test);
std::cout << myint << '\n';
}
$ g++ -otest test.cxx
test.cxx: In Funktion »int main()«:
test.cxx:7:17: Fehler: »stoi« ist kein Element von »std«
int myint = std::stoi(test);
^
$ g++ -otest test.cxx -std=c++11
$ ./test
45
$
edit: I just saw that you used c++11. Are you sure that's making it into your compile options? Check the generated makefile and watch the executed commands to be certain.
Your version seems up to date, so there shouldn't be an issue. I think it may be related to gcc. Try g++ instead.(Most likely automatically linking issue. If you just run gcc on a C++ file, it will not 'just work' like g++ does. That's because it won't automatically link to the C++ std library, etc.). My second advise is try std::atoi.
# I have fixed the issue. std::stoi uses libstdc++. It is about The GNU Standard C++ Library. In gcc you have to link adding -lstdc++. However, in g++, libstdc++ is linked automatically.
using gcc and using g++
Pay attention how it is compiled
using g++: g++ -std=c++11 -O3 -Wall -pedantic main.cpp && ./a.out
using gcc: gcc -std=c++11 -O3 -Wall -pedantic -lstdc++ main.cpp && ./a.out
I think you should set flag like set(CMAKE_EXE_LINKER_FLAGS "-libgcc -lstdc++") (Not tested)
#include <cstdlib>
int myInt = std::atoi(test.c_str());
If you are using Cmake to compile, add line:
"add_definitions(-std=c++11)"
after find_package command.
Use 'set(CMAKE_CXX_STANDARD 11)' for Cmake
I have recently started learning C++ and, since I'm on Linux, I'm compiling using G++.
Now, the tutorial I'm following says
If you happen to have a Linux or Mac environment with development
features, you should be able to compile any of the examples directly
from a terminal just by including C++11 flags in the command for the
compiler:
and tells me to compile using this command: g++ -std=c++0x MY_CODE.cpp -o MY_APP.
Now, what I'm wondering, what is the point of the std=c++0x flag? Is it required, or can I just run g++ MY_CODE.cpp -o MY_APP?
By default, GCC compiles C++-code for gnu++98, which is a fancy way of saying the C++98 standard plus lots of gnu extenstions.
You use -std=??? to say to the compiler what standard it should follow.
Don't omit -pedantic though, or it will squint on standards-conformance.
The options you could choose:
standard with gnu extensions
c++98 gnu++98
c++03 gnu++03
c++11 (c++0x) gnu++11 (gnu++0x)
c++14 (c++1y) gnu++14 (gnu++1y)
Coming up:
c++1z gnu++1z (Planned for release sometime in 2017, might even make it.)
GCC manual: https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Standards.html#Standards
Also, ask for full warnings, so add -Wall -Wextra.
There are preprocessor-defines for making the library include additional checks:
_GLIBCXX_CONCEPT_CHECKS to add additional compile-time-checks for some templates prerequisites. Beware that those checks don't actually always do what they should, and are thus deprecated.
_GLIBCXX_DEBUG. Enable the libraries debug-mode. This has considerable runtime-overhead.
_GLIBCXX_DEBUG_PEDANTIC Same as above, but checks against the standards requirements instead of only against the implementations.
You want to use the C++11 standard (and you are right to want that), but C++11 made a huge progress w.r.t. its older C++98 standard.
But old versions of GCC (i.e. GCC 4.8 or earlier) where not finalized before the standard itself (so they accepted the -std=c++0x flag). I strongly recommend (if you want C++11) to use the latest version of GCC, that is GCC 4.9. A bug fixing GCC 4.9.2 release appeared at end of october 2014. So use it please, and pass it the std=c++11 flag to tell the compiler you want C++11 conformance.
I actually suggest to pass std=c++11 -Wall -Wextra -g to get C++11, all warnings, and debug info. Once you have debugged your program (with gdb, and you'll better also use a recent version of gdb!) you might ask the compiler to optimize with -O2 (and perhaps -mtune=native if you want to optimize for your own computer)
Source for your reference:
main.cpp
#include <iostream>
using namespace std;
int main()
{
cout << "Test main CPP" << endl;
return 0;
}
build.sh
rm demoASI*
echo "**cleaned !!**"
##### C++ 11 Compliance #####
# type ONE
g++ -o demoASI_1 -std=c++0x main.cpp
echo "**rebuild-main-done (C++ 11 Compilation) !**"
# type TWO
g++ -o demoASI_2 -std=c++11 main.cpp
echo "**rebuild-main-done (C++ 11 Compilation) !**"
##### C++ 11+ Compliance #####
# type THREE
g++ -o demoASI_3 -std=c++1y main.cpp
echo "**rebuild-main-done (C++ 11+ (i.e. 1y, but not C++14) Compilation) !**"
###### C++ 14 Compliance ######
# type FOUR
g++ -o demoASI_4 -std=c++14 main.cpp
if [ $? -eq 0 ]
then
echo "**rebuild-main-done (C++ 14 Compilation) !** :: SUCCESS"
else
echo "**rebuild-main-done (C++ 14 Compilation) !** :: FAILED"
fi
Now, execute the script as;
./build.sh (assuming build.sh has execution permission)
You can first check the version of your g++ compiler, as;
g++ --version
The version of g++, after 4.3, has support for the c++11.
Please see, for c++14 support info in compiler.
This is the first time I use clang. What I notices is that any error from clang referencing the std library looks like this:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/ostream:245:7:
^^^ ^^^ ^^^
So it looks like clang links — or at least includes — the gcc libraries.
The command I used: clang++ -c -Wall -Wextra -Werror -g test.cpp -o test.o. (The program had a intentional error just to prove this).
How is this possible? What can I do to make clang use its own libraries (but not break gcc)?
Additional information:
I am on a Ubuntu 14.04 machine.
clang++ --version
Ubuntu clang version 3.5-1ubuntu1 (trunk) (based on LLVM 3.5)
Target: x86_64-pc-linux-gnu
Thread model: posix
g++ --version
g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
I had previously installed several versions (at the same time, used them with update-alternatives) of gcc with apt-get. Right now I have only 4.8 (I have uninstalled the others). Could I have messed up something then? I have never installed clang (I guess it is default with Ubuntu).
Just to clarify: the correct programs compile and run in clang++.
Further tests: I know that gcc didn’t implement yet types like is_trivially_constructible and move operations on iostream in their standard c++11 library (https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html) and that clang has full c++11 conforming library so I tested those compiling with clang and I got the corresponding gcc errors, which only confirms that clang is using gcc libraries.
A very basic program
#include <iostream>
using namespace std;
int main() {
cout << "Yada Yada" << endl;
return 0;
}
gives this error when compiling with -std=c++1y in clang++:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/iostream:39:
...
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/cstdio:120:11: error: no member named 'gets' in the global namespace
using ::gets;
~~^
So right now I can’t compile anything with c++1y in clang.
You need to install libc++ and make clang use it with -stdlib=libc++
I had similar issue: GCC (g++) already was installed on my LinuxMint (Ubuntu base) so when compile with clang, was getting an " error: no member named 'gets' in the global namespace using ::gets ".
resolved by installing libc++-dev (sudo apt-get install libc++-dev) and compiling with -stdlib++ (clang++ -g -std=c++1y -stdlib=libc++ helloworld.cpp -o helloworld)
Your real problem is that you're using C++14 (c++1y was the informal name used to refer to it when it wasn't yet fully formed), with a C++ library belonging to GCC 4.8. GCC 4.8 has complete C++11 support, but hardly even started on C++14 features.
This is caused by C++14 removing std::gets, and the GNU C library anticipating on that by not defining gets in the global namespace while the C++ library has not yet caught up and is trying to make it available in the std namespace.
The proper way to solve this does not require using libc++, just to use a C++ library with C++14 support. GLIBCXX 4.9 (aka libstdc++) already suffices.