I think I'm getting close, but I'm having this error I've been banging my head against the wall on for hours. I'm missing something stupid, and I've gone character by character but I can't find it.
The compiler is giving me
main.cpp:16: undefined reference to `translator::translator(std::istream&)'
collect2: error: ld returned 1 exit status
when I try to compile my program. The command I'm using to compile is:
clear && g++ -g -Wall main.cpp -o Pear
The three sections of use are as follows:
main.cpp
int main(int argc, char* argv[])
{
std::ifstream myFile;
myFile.open(argv[1]);
translator example(myFile);
myFile.close();
return 0;
}
translator.cpp
#include <fstream>
#include <iostream>
#include <string>
#include "translator.h"
translator::translator(std::istream& in)
{
table1(in);
table2(in);
}
translator.h
#ifndef TRANSLATOR
#define TRANSLATOR
#include <fstream>
#include <iostream>
#include <string>
#include "translationTable.h"
class translator
{
private:
translationTable<std::string, int> table1;
translationTable<int, std::string> table2;
translator();
public:
translator(std::istream& in);
};
#endif
Any ideas? I've tried so much, and I've looked up similar problems, but they all have different sources. Thanks in advance!
The command line for g++ needs to include both source files, like this:
g++ -g -Wall main.cpp translator.cpp -o Pear
Otherwise, the compiler has no idea from where to get the implementation of the translator::translator(std::istream&) member function.
*EDIT: * (from the comment)
I thought that basically the use of header files was so that it would know where to get each implementation of the file?
This part is grossly oversimplified, but it should help you get the picture. Recall that the process of producing an executable from C++ sources consists of two major steps - compilation and linking. The g++ program performs them both (it can do just one if you specify -c flags, or pass only .o files).
The compiler and the linker stages of g++ do not "talk" to each other directly. The compiler produces the inputs for the linker, and that's where the communication ends.
Header files are for the compiler. Specifically, they are for the first stage of compilation - the preprocessing. Once the preprocessor has finished, there is no knowledge of where the definitions came from. Even the compiler does not know it, let alone the linker. That is why you need to "help" the linker by supplying all the relevant sources to g++.
You aren't linking translator.o with your application.
g++ -g -c translator.cpp
followed by
g++ -g -Wall main.cpp translator.o -o Pear
Related
I have this simple code:
max = (int) sqrt (number);
and in the header I have:
#include <math.h>
But application still says undefined reference to sqrt. Do you see any problem here? It looks like everything should be okay.
You may find that you have to link with the math libraries on whatever system you're using, something like:
gcc -o myprog myprog.c -L/path/to/libs -lm
^^^ - this bit here.
Including headers lets a compiler know about function declarations but it does not necessarily automatically link to the code required to perform that function.
Failing that, you'll need to show us your code, your compile command and the platform you're running on (operating system, compiler, etc).
The following code compiles and links fine:
#include <math.h>
int main (void) {
int max = sqrt (9);
return 0;
}
Just be aware that some compilation systems depend on the order in which libraries are given on the command line. By that, I mean they may process the libraries in sequence and only use them to satisfy unresolved symbols at that point in the sequence.
So, for example, given the commands:
gcc -o plugh plugh.o -lxyzzy
gcc -o plugh -lxyzzy plugh.o
and plugh.o requires something from the xyzzy library, the second may not work as you expect. At the point where you list the library, there are no unresolved symbols to satisfy.
And when the unresolved symbols from plugh.o do appear, it's too late.
I suppose you have imported math.h with #include <math.h>
So the only other reason I can see is a missing linking information. You must link your code with the -lm option.
If you're simply trying to compile one file with gcc, just add -lm to your command line, otherwise, give some informations about your building process.
Just adding the #include <math.h> in c source file and -lm in Makefile at the end will work for me.
gcc -pthread -o p3 p3.c -lm
Here are my observation, firstly you need to include the header math.h as sqrt() function declared in math.h header file. For e.g
#include <math.h>
secondly, if you read manual page of sqrt you will notice this line Link with -lm.
#include <math.h> /* header file you need to include */
double sqrt(double x); /* prototype of sqrt() function */
Link with -lm. /* Library linking instruction */
But application still says undefined reference to sqrt. Do you see any
problem here?
Compiler error is correct as you haven't linked your program with library lm & linker is unable to find reference of sqrt(), you need to link it explicitly. For e.g
gcc -Wall -Wextra -Werror -pedantic test.c -lm
I had the same issue, but I simply solved it by adding -lm after the command that runs my code.
Example.
gcc code.c -lm
Let's say I have 3 files:
Test.hh
#ifndef TEST_HH_
#define TEST_HH_
class Test
{
int test() const;
};
#endif /* TEST_HH_ */
Test.cc:
#include "Test.hh"
int Test::test() const
{
return 0;
}
main.cc:
#include "Test.cc"
int main()
{
return 0;
}
It does not compile (rather does not link), I understand why, I defined Test::test() in multiple translation units (in main.cc that includes Test.cc and in Test.cc):
g++ -Wall -g -std=c++17 -c main.cc -o main.o
g++ -Wall -g -std=c++17 -c Test.cc -o Test.o
g++ -o bin main.o Test.o
Test.o: In function `Test::test()':
Test.cc:12: multiple definition of `Test::test()'
main.o:Test.cc:12: first defined here
collect2: error: ld returned 1 exit status
Edit: This is NOT my issue, my issue is that with a seemingly identical situation, in a bigger project, the previous example produces a binary (i.e. compiles and links) when, as far as I understand it, it shouldn't. I will now describe the real case with a bit more details and how the problem suddenly arised when previously it was working fine (when it shouldn't have).
--
I am currently working on a large project (~2500 files), and while trying to use the "Test" class above, I ended up having a lot of "multiple definitions" errors at link time. To translate it to our example, it's like I had another class doing this:
OtherClass.hh
#include "Test.hh" // including or using forward declaration led to the same results
//class Test; forward declaration
class OtherClass
{
// Some stuff, whatever
};
I ended up finding that Test.cc was included in another source file (main.cc in my very simplified exemple though it was in another "someClass.cc" in my actual project). After including the header instead of the source, it compiled again. What's more surprising is that other classes had been using Test.hh the same way until then without any problems.
Since I was really surprised, I ended up doing a grep on all my files and found that another 2 source files had included other sources files as well.
WhateverClass.cc
#include "Test2.cc"
YetAnotherClass.cc
#include "Test3.cc"
All those files are compiled and contain function definitions yet the linker does not complain. I tried doing a compilation from scratch and it still worked.
So my question is: Why does this compile even though some source files include others and all of them are compiled ? And why did it suddenly stop working even though I just included the header of one of those source files just like other classes had been doing ? Is there a kind of "undefined behavior" for cases like this ?
If it is of any help, my project is using CMake. I tried compiling with ninja or Make with the same results.
I had a similar question before. So, here's what I learned- never include source file. Only include header files. Your error comes from including a source (.cc) file in your main. You should include Test.hh instead. Declare all your classes and functions in header, include that header to all the source files where the definitions and the calls are.
I have the following project structure:
test_main.cc
#define CATCH_CONFIG_MAIN
#include "catch2.hpp"
test1.cc
#include "catch2.hpp"
#include "test_utils.hpp"
TEST_CASE("test1", "[test1]") {
REQUIRE(1 == 1);
}
test2.cc
#include "catch2.hpp"
#include "test_utils.hpp"
TEST_CASE("test2", "[test2]") {
REQUIRE(2 == 2);
}
test_utils.hpp
#pragma once
#include <iostream>
void something_great() {
std::cout << ":)\n";
}
If I compile using something like clang++ -std=c++17 test_main.cc test1.cc test2.cc, the function something_great is defined in both test1.o and test2.o. This leads to an error like
duplicate symbol __Z15something_greatv in:
test1.cc.o
test2.cc.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
In the Scaling Up section of the Catch2 documentation, they mention that in order to split up your tests you may want to
Use as many additional cpp files (or whatever you call your
implementation files) as you need for your tests, partitioned however
makes most sense for your way of working. Each additional file need
only #include "catch.hpp"
but in the examples section of the documentation I don't see a use case like mine. I read this blog post which describes three solutions which don't appeal to me: defining functions as macros, or making functions static or inline.
Is there another way to compile these files which yield a single executable with the main function defined by test_main.cc?
This actually has nothing to do with Catch or testing. When you #include a file in C++, it gets copy-pasted at the #include line verbatim. If you put free function definitions in headers, you would see this problem building your actual program, etc.
The underlying problem is that #include is not the same kind of import-a-module directive as is the equivalent directive (import, require, etc.) in most languages, which do the sane thing in a situation like this (confirm that the header is the same one we've already seen and ignore the repeated method definition).
The commenter that suggested you write inline is technically correct, in the sense that this will "solve your problem" because your compiler won't generate object code for the method multiple times. However, it doesn't really explain what's going on or address the underlying issue.
The clean solution is:
In test_utils.hpp, replace the method definition with a method declaration: void something_great();.
Create test_utils.cc with the definition of the method (which you currently have in the .hpp).
clang++ -std=c++17 test1.cc -c
clang++ -std=c++17 test2.cc -c
clang++ -std=c++17 test_main.cc -c
clang++ -std=c++17 test_utils.cc -c
clang++ -std=c++17 test1.o test2.o test_utils.o test_main.o
I also recommend you read this: What is the difference between a definition and a declaration?
Explicitly:
// test_utils.hpp
#pragma once
// This tells the compiler that when the final executable is linked,
// there will be a method named something_great which takes no arguments
// and returns void defined; the definition lives in test_utils.o in our
// case, although in practice the definition could live in any .o file
// in the final linking clang++ call.
void something_great();
And:
// test_utils.cpp
#include "test_utils.hpp"
#include <iostream>
// Generates a DEFINITION for something_great, which
// will get put in test_utils.o.
void something_great() { std::cout << "Hi\n"; }
It seems you are worried about "recompiling Catch" every time you make a change to a test. I hate to break it to you, but you are in C++ land now: you are going to be recompiling stuff pointlessly a lot. Header-only libraries like Catch MUST be "recompiled" to some extent when a source file including them changes, because for better or worse, if the source file or a header file included transitively from the source file includes catch2.hpp, then the source code of catch2.hpp will get parsed by the compiler when that source file is read.
After some experimentation, I found a reasonable solution which doesn't require you to fully recompile Catch any time you make a change to a test.
Define test_main.cc in the same way as before:
#define CATCH_CONFIG_MAIN
#include "catch2.hpp"
Add another .cc file, test_root which includes your test files as headers:
#include "test1.hpp"
#include "test2.hpp"
Change your test sources to headers:
test1.hpp
#pragma once
#include "catch2.hpp"
#include "test_utils.hpp"
TEST_CASE("test1", "[test1]") {
REQUIRE(1 == 1);
}
test2.hpp
#pragma once
#include "catch2.hpp"
#include "test_utils.hpp"
TEST_CASE("test2", "[test2]") {
REQUIRE(2 == 2);
}
Compile separately
clang++ -std=c++17 test_main.cc -c
clang++ -std=c++17 test_root.cc -c
clang++ test_main.o test_root.o
Where test_main.cc needs only be compiled once. test_root.cc will need to be recompiled whenever you change your tests and of course you must relink the two object files.
I will leave this answer unaccepted for now in case there are better solutions.
Let me first set the context, it is CERN's ROOT and CINT and ACLiC etc.
Suppose I have a main macro named macro.cpp and two headers h1.cpp (contains the definition of a function) and h1.h containing the declaration of the function defined in h1.cpp similarly I have h2.cpp and h2.h. The main program macro.cpp calls those functions inside h1 and h2. I was successful compiling the source files using:
root [0] .L h1.cpp+
root [1] .L h2.cpp+
root [2] .L macro.cpp+
which generated three .so files macro_cpp.so, h1_cpp.so and h2_cpp.so. I want to know what to do with them ? How do I link them so that I have something like a "macro.out" or something like that (a single executable file of some kind) which I can execute (although I don't know how !) and achieve whatever I wished to achieve with the macro.
Note: If I just load all the files using .L file_name.cpp etc and just execute the main macro using .x macro.cpp then everything works fine and I have results, but this is not what I want ! I want to compile like we do in usual g++ and by the way in every forum everyone keeps advising on compiling using .L file_name.cpp+ or ++ .. I would really like to know the whole story. Because nobody seems to explain beyond .L file_name.cpp+ .. what next ? What to do with the .so etc.
I am a beginner, I will really appreciate a simple and step by step answer and explanation.
Thanks.
Edit-1: I am working with:
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Edit-2: ROOT related information:
ROOT 5.34/36 (v5-34-36#v5-34-36, dic 07 2016, 23:31:51 on linuxx8664gcc)
CINT/ROOT C/C++ Interpreter version 5.18.00, July 2, 2010
If you want to compile and link you can use a standard compiler instead of Cint/Aclic.
For example, assuming you are working on a *nix platform, you can use the example files below:
h1.h
int add_one(int a);
h1.cpp
#include "h1.h"
int add_one(int a)
{
return a+1;
}
h2.h
#include <TLorentzVector.h>
TLorentzVector multiply_by_two(const TLorentzVector v);
h2.cpp
#include "h2.h"
TLorentzVector multiply_by_two(const TLorentzVector v)
{
return 2.0*v;
}
macro.cpp
#include "h1.h"
#include "h2.h"
#include <TLorentzVector.h>
#include <iostream>
using std::cout;
using std::endl;
int main()
{
int a = 0;
TLorentzVector v;
v.SetPtEtaPhiM(1.0, 0.0, 0.0, 0.0);
cout<<"calling add_one on "<<a<<": "<<add_one(a)<<endl;
cout<<"calling multiply_by_two on "<<v.Pt()<<": "<<multiply_by_two(v).Pt()<<endl;
return 0;
}
Then you can compile with
g++ -c -g -Wall `root-config --cflags` h1.cpp
g++ -c -g -Wall `root-config --cflags` h2.cpp
g++ -c -g -Wall `root-config --cflags` macro.cpp
and link with
g++ `root-config --glibs` h1.o h2.o macro.o
The executable will be a.out:
$ ./a.out
calling add_one on 0: 1
calling multiply_by_two on 1: 2
You can put these g++ commands in a script or, when you start having several files and directories, you can write your make file (or cmake). For this last step, see for example the tutorial here
http://www-pnp.physics.ox.ac.uk/~brisbane/Teaching/Makefiles/Tutorial_1_Makefiles_and_ROOT.pdf
Note 1: one advantage of using g++ is that you will get clear error messages when something doesn't compile. The error messages from Cint can
be difficult to understand--although this is very much improved in root 6 with Cling.
Note 2: another advantage of using a standard compiler is that you will be able to easily link your main executable against libraries other than root.
This answer is based mostly on the answer by user2148414, but if one follows the answer will notice that there were some issues with the method of linking the source (*.cpp) files. My answer also addresses another important object called a TApplication that will play a crucial role in such applications involving root libraries. The following linking step:
g++ `root-config --glibs` h1.o h2.o macro.o
will likely show a lot of errors complaining about the root objects like TWhatever (in user2148414's answer TLorentzVector will show problems). In the comments to that answer one can find the discussion on including various physics libraries that can solve the problem but without discussing that (and I am not comfortable either :) ) let me write down the command that solves everthing.
This procedure is a one-liner, that is no need to compile individual files, create *.cpp files and *.h files as discussed in that answer then compile and link and create a single executable named "someExecutable" using:
g++ macro.cpp h1.cpp h2.cpp `root-config --libs --cflags` -o someExecutable
or better (and one should do it)
g++ -Wall -Wextra -Werror -pedantic -std=c++14 macro.cpp h1.cpp h2.cpp `root-config --libs --cflags` -o someExecutable
This will solve my original answer but for completeness I would like to add a few more things.
TApplication
My original motivation was to create an application that talks to "ROOT" but I didn't want to work with the ROOT shell, CINT, ACLiC etc and wanted to work entirely with g++. user2148414's and my answer will solve the part of creating an application but the application will not serve any purpose, it will run, create histograms draw them and do all the stuff but all the canvases will close in the end when the code reaches "return 0;". To keep the canvases open we will need "TApplication". So the consider the main of user2148414's answer, I am going include just two more lines and include two arguments to the main:
macro.cpp
#include "h1.h"
#include "h2.h"
#include <TLorentzVector.h>
#include <iostream>
using std::cout;
using std::endl;
int main(int argc, char* argv[]) //introduced arguments to main
{
// here I introduce TApplication
TApplication* SomeApp = new TApplication("SomeApp",&argc, argv);
int a = 0;
TLorentzVector v;
v.SetPtEtaPhiM(1.0, 0.0, 0.0, 0.0);
cout<<"calling add_one on "<<a<<": "<<add_one(a)<<endl;
cout<<"calling multiply_by_two on "<<v.Pt()<<": "<<multiply_by_two(v).Pt()<<endl;
//and just before returning 0
SomeApp->Run();
return 0;
}
I get the error
"/usr/include/c++/5/cstddef:51:11: error: ‘::max_align_t’ has not been declared
using ::max_align_t;
^"
So I should update the libraries because I find this solution:
"A workaround until libraries get updated is to include <cstddef> or <stddef.h> before any headers from that library."
I wrote some command on the Ubuntu terminal such as:
bash $ sudo apt-get install apt-file
bash $ sudo apt-file update
bash $ apt-file search stddef.h
Then still the error exist.
Thank you
In the .cpp file where this compile error occurs you need to add
#include <cstddef>
before any of the other headers, e.g.
main.cpp (broken)
#include <cstdio>
int main()
{
using ::max_align_t;
puts("Hello World");
return 0;
}
Try to compile that:
$ g++ -std=c++11 -o test main.cpp
main.cpp: In function ‘int main()’:
main.cpp:5:10: error: ‘::max_align_t’ has not been declared
using ::max_align_t;
^
Then fix it:
main.cpp (fixed)
#include <cstddef>
#include <cstdio>
int main()
{
using ::max_align_t;
puts("Hello World");
return 0;
}
Compile and run it:
$ g++ -std=c++11 -o test main.cpp
$ ./test
Hello World
I compiled some code with GNU C++ 4.9 on CentOS, and the issue was not solved by ensuring top position #include (or by the older header name stddef.h).
Weird enough, I searched all header files of the compiler libraries for the global definition of max_aling_t as declared in the offending using declaration... and found none! Could it be in some 'internal compiled header?
So I simply commented-out the "using ::max_align_t;" line in the standard header (not proud of doing this indeed) and it solved the problem... and code is running...
if anyone can explain what is the meaning/impact of this max_align_t ?
I also commented-out the using ::max_align_t; line in /usr/include/c++/4.9/cstddef, while, code is running, but I don't know if there are any consequences by doing this...