Compiling on linux with c++ standard libraries - c++

Hi have the following example code:
func.h - header file for functions
#include <vector>
#include <tuple>
using std::vector;
using std::tuple;
tuple <double,double> A(vector<int>& n);
func.cpp - function cpp file
#include <iostream>
#include <vector>
#include <tuple>
using namespace std;
tuple <double,double> A(vector<int>& n)
{
double a1=n.size();
double a2=a1+0.5;
return make_tuple(a1,a2);
}
main.cpp - main cpp file
#include <iostream>
#include <vector>
#include <tuple>
#include "func.h"
using namespace std;
int main()
{
double a1,a2;
vector<int> n;
n.push_back(1);
n.push_back(2);
tie(a1,a2)=A(n);
return 0;
}
This compiles well in visual studio.
I have a problem compiling it on Linux (gcc version 4.4.7 20120313 Red Hat 4.4.7-11) with:
g++ -03 -std=c++0x main.cpp func.cpp -lm
It does not compile, I get the following errors:
1. In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/array:35,from main.cpp:5:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/c++0x_warning.h:31:2: error: #error This file requires compiler and library suppcoming ISO C++ standard, C++0x. This support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options.
2. ‘std::tuple’ has not been declared
3. expected constructor, destructor, or type conversion before ‘<’ token
Any guidance on how to deal with this will be helpful!

Surprisingly the error seems to tell you that std=c++0x is not set.
Double check your compilation command. it should be
g++ -std=c++0x -o b main.cpp func.cpp -O3 -lm
and not
g++ -o -std=c++0x b main.cpp func.cpp -03 -lm
as in the original question.

You are telling GCC to output to the file named "-std=c++0x", and thus not setting that option at all, leading to this error. What it does with "b" afterwards, I have no idea. But you should always do "-o outputfilename" and not put other options between the "-o" option and its argument.

I cut and pasted your three files (func.h, func.cpp and main.cpp) and I can assure you that on my Linux box (CentOS 7.2) with g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4) everything works fine (your original command had some errors):
g++ -o myProg -O3 -std=c++0x main.cpp func.cpp -lm
Update your GCC (even from sources if you have several hours ;) ) .

Since you want to run an executable (compiled from recent C++11 or C++14 source code) on a server with an old version of Linux and of GCC -you have GCC 4.4 which does not support recent C++ standards, because it appeared in 2009 before the publication date (2011) of C++11- you could try the following:
install a recent Linux distribution on your own laptop (or computer) and check that its GCC compiler is at least GCC 5 (and preferably GCC 6) by running g++ --version (you might need to use g++-5 instead of g++, etc...)
compile and link statically your program on that laptop using g++ -static -std=c++14 -Wall func.cpp main.cpp -lm -o mybinprog (and perhaps also -O3 if you want to optimize and/or -g for debugging -better do the debugging locally-)
copy (e.g. using scp mybinprog remotehost:) the executable to the remote server and run it there
It is very probable (but not certain) that a statically linked executable built on a newer Linux (laptop) would run on some older Linux server.
BTW, to compile a multi-source file program, better learn how to use GNU make
Notice that order of program arguments to g++ matters a big lot, so read the documentation about Invoking GCC.
PS. Technically you might even try to link dynamically the C library and statically the C++ standard library.

Related

Code compiles with g++ 5.2.1 but not with g++ 4.9.3

Why this code compiles using g++ 5.2.1, but fails with g++ 4.9.3?
//exception.h
class MyError: public std::runtime_error
{
public:
using std::runtime_error::runtime_error;
};
// nothing else here
//main.cpp
#include <iostream>
#include "exception.h"
int main() {}
5.2.1 compilation:
$ g++ --version
g++ 5.2.1
$ g++ -std=c++11 -c main.cpp -o main.o
$ g++ main.o -o a.out
Compilation successfull.
4.9.3 compilation:
$ g++ --version
g++ 4.9.3
$ g++ -std=c++11 -c main.cpp -o main.o
$ g++ main.o -o a.out
In file included from main.cpp:2:0:
exception.h:3:1: error: expected class-name before ‘{’ token
{
^
exception.h:5:14: error: ‘std::runtime_error’ has not been declared
using std::runtime_error::runtime_error;
....
Solution is to add #include <stdexcept> to exception.h
Now it works with both versions.
When I remove #include <iostream> from main.cpp, then compilation fails even with 5.2.1 version and #include <stdexcept> is required too.
Why this code works on 5.2.1 version without including stdexcept header?
It's included in iostream on 5.2.1 version but not in 4.9.3 version? Reading GCC changes didn't help.
The standard library headers are allowed to include other headers, but there are no guarantees.
Back in the ancient days of g++ 4.0 and 4.1, you could pull in most of the standard library with just #include <iostream> and #include <deque>. But that stopped working in version 4.3 (or something like that).
In order for your code to be portable it should explicitly include all the required headers.

Compiler command and GCC version

I'm taking part in a programming contest and the requirement is that code will be compiled using following command:
g++ -std=c++11 -O2 -o a.out orienteering.cpp
How do I check if my code works for this command? (I use DevC++ for coding and it has automatic compilation).
Also compiler should be GCC 4.8.2 or later. What does this mean? Is my older GCC version (4.7.2) not suitable?
You check your code by placing it in a file named orienteering.cpp, and running this command in the same directory:
g++ -std=c++11 -O2 -o a.out orienteering.cpp
If the compiler spits out any messages at all then you have a problem. If the compiler is silent and creates a file named a.out, then all is well.
GCC 4.7.2 does not meet the criteria "GCC 4.8.2 or later".

How do I compile C++ with Clang?

I have installed Clang by using apt-get in Ubuntu, and I can successfully compile C files using it. However, I have no idea how to compile C++ through it. What do I need to do to compile C++?
The command clang is for C, and the command clang++ is for C++.
I do not know why there is no answer directly addressing the problem. When you want to compile C++ program, it is best to use clang++, instead of using clang. For example, the following works for me:
clang++ -Wall -std=c++11 test.cc -o test
If compiled correctly, it will produce the executable file test, and you can run the file by using ./test.
Or you can just use clang++ test.cc to compile the program. It will produce a default executable file named a.out. Use ./a.out to run the file.
The whole process is a lot like g++ if you are familiar with g++. See this
post to check which warnings are included with -Wall option. This
page shows a list of diagnostic flags supported by Clang.
A note on using clang -x c++: Kim Gräsman says that you can also use
clang -x c++ to compile CPP programs, but that may not be always viable. For example, I am having a simple program below:
#include <iostream>
#include <vector>
int main() {
/* std::vector<int> v = {1, 2, 3, 4, 5}; */
std::vector<int> v(10, 5);
int sum = 0;
for (int i = 0; i < v.size(); i++){
sum += v[i]*2;
}
std::cout << "sum is " << sum << std::endl;
return 0;
}
clang++ test.cc -o test will compile successfully, but clang -x c++ will
not, showing a lot of undefined reference errors. So I guess they are not exactly equivalent. It is best to use clang++ instead of clang -x c++ when compiling c++ programs to avoid extra troubles.
clang version: 11.0.0
Platform: Ubuntu 16.04
Also, for posterity -- Clang (like GCC) accepts the -x switch to set the language of the input files, for example,
$ clang -x c++ some_random_file.txt
This mailing list thread explains the difference between clang and clang++ well: Difference between clang and clang++
Solution 1:
clang++ your.cpp
Solution 2:
clang your.cpp -lstdc++
Solution 3:
clang -x c++ your.cpp
I've had a similar problem when building Clang from source (but not with sudo apt-get install. This might depend on the version of Ubuntu which you're running).
It might be worth checking if clang++ can find the correct locations of your C++ libraries:
Compare the results of g++ -v <filename.cpp> and clang++ -v <filename.cpp>, under "#include < ... > search starts here:".
Open a Terminal window and navigate to your project directory. Run these sets of commands, depending on which compiler you have installed:
To compile multiple C++ files using clang++:
$ clang++ *.cpp
$ ./a.out
To compile multiple C++ files using g++:
$ g++ -c *.cpp
$ g++ -o temp.exe *.o
$ ./temp.exe

mingw linker error when using vector templates

I'm using MinGw on Windows 7. The following simple program compiles fine, but the linker complains and I do not understand what's wrong:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::vector<int> iv;
iv.push_back(7);
cout << iv.back() << endl;
return 0;
}
the compiler/linker messages look as follows:
mingw32-g++.exe -Wall -fexceptions -std=c++0x -Wall -g -std=c++0x -Wall -g -frepo -IC:\cppbuchincludes\include -IG:\Boost -IG:\Users\thomas\cpp\STLUsage\\include -c G:\Users\thomas\cpp\STLUsage\main.cpp -o obj\Debug\main.o
mingw32-g++.exe -o bin\Debug\STLUsage.exe obj\Debug\main.o G:\Boost\stage\lib\libboost_filesystem-mgw45-mt-d-1_45.dll.a G:\Boost\stage\lib\libboost_regex-mgw45-mt-d-1_45.dll.a G:\Boost\stage\lib\libboost_system-mgw45-mt-d-1_45.dll.a G:\Boost\stage\lib\libboost_thread-mgw45-mt-1_45.dll.a G:\Boost\stage\lib\libboost_unit_test_framework-mgw45-mt-d-1_45.dll.a
collect: recompiling G:\Users\thomas\cpp\STLUsage\main.cpp
collect: relinking
collect2: '_ZNSt12_Vector_baseIiSaIiEEC1Ev' was assigned to 'obj\Debug\main.rpo', but was not defined during recompilation, or vice versa
obj\Debug\main.o: In function `vector':
c:/mingw/bin/../lib/gcc/mingw32/4.5.2/include/c++/bits/stl_vector.h:208: undefined reference to `std::_Vector_base<int, std::allocator<int> >::_Vector_base()'
(...and so on...)
I can use templates I defined myself.
I have that MinGw binary from a book and followed the instructions in that book regarding compiler settings. In particular the references to the Boost libs are taken from there.
This must be a simple thing, I just want to make trivial use of the STL.
Edit following the advice given in an answer, I replaced the binary to be used to compile by g++.exe in the Settings -> Compiler and debugging -> toolchain executables dialog, but I'm getting the same error messages (with mingw32-g++.exe now replaced by g++.exe).
Edit (once more) this has to be problem eith the Code::Blocks settings, since compiling using g++ from the command line works just fine.
Use g++ to compile and link the program. mingw32-g++.exe doesn't do that.
FAQ says,
What's the difference between gcc and mingw32-gcc?
The mingw32-gcc, mingw32-g++, etc. binaries exist as an aid to cross development. They are created in a typical build of gcc. They are therefore distributed as the maintainers of GCC meant them to be. The gcc.exe indicates that the binary produces binaries for a target equal to the build, while the mingw32-gcc binary produces binaries to be executed on the mingw32 target.
So I guess the problem is because of mingw32-g++.exe which you're not supposed to use, for normal build.
Try these:
g++ program.cpp //simple build
g++ program.cpp -Wall //build with all warnings enabled
g++ program.cpp -Wall -O2 //enable warnings and optimization level 2
g++ program.cpp -std=c++0x //use C++11 features
Hope that helps.

g++ and c++0x specification support

although it's been said that the support for c++0x new features in g++ are in experimental mode, many gcc developer claimed that you can use most of the new features in your codes and get the program to work.
but when I try to compile this simple program it results in segmentation fault. Why?
#include <thread>
#include <iostream>
void my_thread_func()
{
std::cout<<"hello"<<std::endl;
}
int main()
{
std::thread t(my_thread_func);
t.join();
}
g++ -std=c++0x -Wall -o run main.cc
I linked the executable with pthread library and it worked! I did not see any missing shared library dependency (ldd), but seems like std C++ library implementation on Linux uses pthread internally.
g++ thread.cpp -o thread -Wall -std=c++0x -lpthread