C++ linker error despite using g++, clang etc to compile - c++

I'll start by showing you the error I have been getting:
Henrys-MacBook-Pro-2:assignment1 HenryDashwood$ clang++ main.cpp
Undefined symbols for architecture x86_64:
"clear()", referenced from:
_main in main-a61991.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I've been trying to move some functions into a source.cpp file with prototypes in a header.h file. The code works fine when I have it all in the main.cpp file. It also works when I move the function prototype to a header file. However, when I then also move the functions to the source file, it errors me! Here are the relevant bits of my code:
main.cpp
#include <string>
#include <iostream>
using namespace std;
#include "header.h"
int main()
{
char quit, choice;
int term, day, hour;
string termName, dayName;
clear();
return 0;
}
header.h
#define TERMS 4
#define DAYS 7
#define HOURS 8
struct TTcell
{
string subject;
string lecturer;
string roomName;
};
struct TTcell timetables[8][7][4];
void clear();
source.cpp
#include <string>
#include <iostream>
using namespace std;
#include "header.h"
void clear()
{
for (size_t i = 0; i < TERMS; i++) {
for (size_t j = 1; j <= DAYS; j++) {
for (size_t k = 1; k <= HOURS; k++) {
timetables[k][j][i].subject = "";
timetables[k][j][i].lecturer = "";
timetables[k][j][i].roomName = "";
}
}
}
}
This is an example using one function to keep the question readable. They all seem to have the same affliction. I saw on other posts people got similar errors because of the compiler they were using. I've tried c++, g++ and clang++, all to no avail.
Thank you in advance for any ideas you come up with!

You have two options to make this compile.
Compile all the cpp files on one line
g++ main.cpp source.cpp -o main
Compile separately and link
g++ -c main.cpp
g++ -c source.cpp
g++ -o main main.o source.o

This is a bog-standard failure to bring in your source files, and has nothing to do with your compiler.
Henrys-MacBook-Pro-2:assignment1 HenryDashwood$ clang++ main.cpp
You didn't build & link source.cpp.
So, as far as Clang knows, the definition for clear() indeed does not exist.
Henrys-MacBook-Pro-2:assignment1 HenryDashwood$ clang++ main.cpp source.cpp

Related

c++ include header get failed

recently I've started learning c++. When I tried to write my header file, I got include error. Here is my code:
First is the header file(header.h)
#pragma once
void print(int);
and then is its cpp file(header.cpp)
#include "header.h"
#include <iostream>
using namespace std;
void print(int x){
cout << x << endl;
}
and finally my main cpp program(main.cpp)
#include <iostream>
#include "./header.h"
using namespace std;
int main(){
int x = 123;
print(x);
}
Here is the error, I can't figure out what it's saying orz
cd "/Users/yianchen/Desktop/cpp practice/" && g++ main.cpp -o main &&
"/Users/yianchen/Desktop/cpp practice/"main Undefined symbols for
architecture x86_64: "print(int)", referenced from:
_main in main-90c620.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to
see invocation)
I have searched for some solution, when I use
#include "header.cpp"
It works fine, but I see guys unrecommended using #include some_file.cpp
By the way, I use visual studio code and use code runner. Thanks!
The easiest solution would be to do something like the following
g++ header.cpp main.cpp
This will make sure that the function defined in header.cpp is compiled together with the code that uses it.
Normal usage would be to compile header.cpp, not to include it in another .cpp source. Then the linker will put the pieces together.

Issues with compiling multiple files

So I'm trying to write a bit of code to work with sudoku puzzles, and I keep getting errors when I try to compile, and each time i compile it deletes the driver.
heres the code for the driver:
/*
* Jared C
* C++ Project
*/
#include <iostream>
#include "SudokuBoard.h"
using namespace std;
int main()
{
SudokuBoard board("sudoku.txt");
board.printBoard();
}
And here's the header file
/*
* Jared C
* SudokuBoard.h
*/
#ifndef __SUDOKUBOARD_H_INCLUDED__
#define __SUDOKUBOARD_H_INCLUDED__
#include <iostream>
#include <string>
class SudokuBoard
{
private:
int content[9][9];
public:
SudokuBoard(std::string filename);
void printBoard();
int getNumAt(int, int);
void setNumAt(int, int, int);
};
#endif
And finally the Sudoku Board.cpp
/*
* Jared C
* SudokuBoard.cpp
*/
#include <iostream>
#include <fstream>
#include "stdlib.h"
#include "SudokuBoard.h"
using namespace std;
SudokuBoard::SudokuBoard(string filename)
{
string output;
string line;
int count = 0;
ifstream file;
file.open(filename.c_str());
if (file.is_open())
{
while (getline (file, line))
{
output += line;
}
file.close();
}
else cout<< "unable to open file" << endl;
for(int y = 0; y < 9; y++)
{
for(int x = 0; x < 9; x++)
{
content[x][y] = atoi(output.substr(count,1).c_str());
count ++;
}
}
}
void SudokuBoard::printBoard()
{
string output = "\n";
for(int y = 0; y < 9; y++)
{
if(y%3==0)
{
output += '\n';
}
for(int x = 0; x < 9; x++)
{
if(x%3==0)
{
output += " ";
}
output += content[x][y];
output += "\n";
}
}
cout<<output<<endl;
}
int SudokuBoard::getNumAt(int x, int y)
{
return content[x][y];
}
void SudokuBoard::setNumAt(int x, int y, int value)
{
content[x][y] = value;
}
When i call gcc -c SudokuBoard.cpp I get the SudokuBoard.o file just fine, but when I then call 'gcc -o Driver.cpp SudokuBoard.o' I get a huge wall of error messages, heres a sample of them:
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 0 has invalid symbol index 11
SudokuBoard.cpp:(.text+0x34): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string()'
SudokuBoard.cpp:(.text+0x43): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string()'
And it deletes Driver.cpp Any idea what I'm doing wrong?
Your command line is incorrect:
gcc -o Driver.cpp SudokuBoard.o
Instructs gcc to link the object file SudokuBoard.o as an executable file named Driver.cpp. No surprise that it first erases the destination file.
Furthermore, you do not specify the runtime library to link with and gcc does not default to C++: this explains the error message.
You should instead write:
g++ -o Sudoku Driver.o SudokuBoard.o
Use g++ to compile C++ code, not the common C-oriented gcc.
g++ invokes gcc for compilation and linking with the right options for C++.
In short, it's a good idea to use a C++ compiler for C++ source code, a Fortran compiler for Fortran source code, and so on.
Also, for the issue of “And it deletes Driver.cpp”, simply don't specify that source file as an output file.
The problem is that the -o option with gcc is used for specifying the output file. If you write
gcc -o Driver.cpp SudokuBoard.o
you tell the compiler to create an executable file named Driver.cpp out of the object file SudokuBoard.o. But as SudokuBoard.o has no main method, this will fail, therefore the error messages.
Try
gcc -c SudokuBoard.cpp
gcc -c Driver.cpp
gcc -o Sudoku SudokuBoard.o Driver.o
instead.
The compiler is telling you it can't find the implementation for std::basic_string<...>.
You need to tell the compiler how to find the compiled code for std::basic_string<...>. Much how with your own code, if you tried to build an executable out of just Driver.cpp the compiler would complain about missing SudokuBoard references until you told it about SudokuBoard.o.
In this case you need to tell the compiler about the C++ standard library. This library are usually shipped with your distribution. On Windows in the form of dll files, on OS X dylib files and on Linux so files. Conceptually they are similar, many bags of .o files all together. Either way, you tell the linker to link to the C++ standard library.
gcc calls the C++ standard library libstdc++, so your command would be something like: gcc -o Driver Driver.cpp SudokuBoard.o -lstdc++.

How to resolve Duplicate Symbol Error?

I'm compiling 2 C++ files together. 4 if you include the header files. The problem is, I keep getting "Duplicate Symbol" errors when the linker tries to link the files together.
Here are my files.
main.h
int test2();
main.cc
#include "main.h"
#include "test.h"
int test2(int test) {
return 0;
}
int main() {
test2(test());
return 0;
}
test.h
int hello = 10;
int test();
test.cc
#include <iostream>
#include "test.h"
using namespace std;
int test() {
cout << hello << endl;
return 0;
}
I think I'm doing something simple wrong. Can someone please point out what I'm doing wrong.
Here's how I'm compiling the files.
c++ main.cc test.cc -o main
Here's the error I get:
duplicate symbol _hello in:
/var/folders/nj/568_95bj4dg9v11l_mksv_2m0000gn/T/main-3becdd.o
/var/folders/nj/568_95bj4dg9v11l_mksv_2m0000gn/T/test-e84473.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
In header file, declare the variable:
extern int hello;
In exactly one source file, define the variable:
int hello = 10;
Do not define variables in headers - that's equivalent to defining them in every source file that includes the header, and that's what's causing your linker error.
You can simply define hello as a "static" (global) variable
static int hello = 10;
More information is mentioned in a similar question:
Duplicate symbols while linking

Error when trying to separating class into .h, .cpp

This is a minimal program that I made to understand this problem better.
ADT.h
#ifndef ADT_H
#define ADT_H
class ADT {
public:
void print();
};
#endif
ADT.cpp
#include <iostream>
#include "ADT.h"
using namespace std;
void ADT::print()
{
cout << "This program works." << endl;
}
testADT.cpp
#include <iostream>
#include "ADT.h"
using namespace std;
int main(void)
{
ADT sa;
sa.print();
return 0;
}
I compiled it with the vim/minGW compiler my school provided me like so:
g++ testADT.cpp
Which produced the following error:
C:\Users\King\AppData\Local\Tempcc6eoWAP.o:testADT.cpp(.text+0x15 reference to 'ADT::print()'
collect2.exe error: ld returned 1 exit status
Can you explain this error message and indicate the error in my code?
You didn't post the error, but I see that you're missing the semicolon after void print()in the header.
EDIT: That's a linker error. Each source file should be compiled into an object file; then the object files linked:
g++ -c -oADT.o ADT.cpp
g++ -c -otestADT.o testADT.cpp
g++ -oADT ADT.o testADT.o
You can also do it in one line as in michaeltang's answer, but then you can't recompile the sources individually (the 2 step method scales better).
You should also compile ADT.cpp
g++ -o testadt testADT.cpp ADT.cpp

C++ compiling problem; class methods

I have started writing a very simple class, and all kinds of class methods seem to give me problems. I hope the problem is me and the solution is simple.
The command g++ -o main main.cpp gives the folowing output:
/usr/bin/ld: Undefined symbols:
Lexer::ConsoleWriteTokens()
collect2: ld returned 1 exit status
main.cpp:
#include<iostream>
#include"lexer.h"
int main(){
Lexer lexhnd = Lexer();
std::cout << "RAWR\n";
lexhnd.ConsoleWriteTokens();
std::cout << "\n\n";
return 0;
}
lexer.h:
#ifndef __SCRIPTLEXER
#define __SCRIPTLEXER
#include <iostream>
#include <string>
#include <vector>
#define DEF_TOKEN_KEYWORD 0
struct token{
int flag;
std::string data;
};
class Lexer
{
public:
// bool IsTrue();
// bool AddLine(char * line);
void ConsoleWriteTokens(void);
private:
std::vector<token> TOK_list;
};
#endif
lexer.cpp:
bool Lexer::IsTrue(){
return true;
};
bool Lexer::AddLine(char * line){
token cool;
cool.data = line;
TOK_list.push_back(cool);
string = line;
return true;
};
void Lexer::ConsoleWriteTokens(void){
for (int i = 0; i < TOK_list.size(); i++){
std::cout << "TOKEN! " << i;
}
return 0;
};
I am using g++ in xcode btw.
Thankyou very much in advance, I have been on this problem for a few hours.
EDIT:
g++ -o main lexer.h main.cpp
or
g++ -o main lexer.cpp main.cpp
or
g++ -o main main.cpp lexer.cpp
do NOT work either.
-Hyperzap
Your not compiling the lexer.cpp code.
Try
g++ -o main main.cpp lexer.cpp
as your compilation command.
PROBLEMS IN THE lexer.cpp
You probably want to include the lexer header in the lexer.cpp file
#include "lexer.h"
Also, you don't want to return an integer from void functions.
void Lexer::ConsoleWriteTokens(void){
for (int i = 0; i < TOK_list.size(); i++){
std::cout << "TOKEN! " << i;
}
//This function is void - it shouldn't return something
//return 0;
};
Finally, you have some problems withs this function
bool Lexer::AddLine(char * line){
token cool;
cool.data = line;
TOK_list.push_back(cool);
//what is this next line trying to achieve?
//string = line;
return true;
};
I'm not sure what you are trying to achieve with the line I commented out,
it doesn't seem to do anything and string isn't defined (did you mean std::string mystring = line;)
Finally, don't forget to uncomment the functions declaired in lexer.h that you are defining in lexer.cpp.
Include all the .cpp files in the command line, like this:
g++ -o main main.cpp lexer.cpp
When your project grows, it becomes wise to manage your project in some automatic way: Makefiles, ant, or some IDE-integrated project file.
Well g++ -o main main.cpp lexer.cpp sould do the trick. However I suggest making makefile files. When having a multiple amount of file they come in handy.
I would also suggest adding some optimization to your compilation like -O3 or -O2 (O is a letter o not zero digit!). The difference in execution speed is very noticable. Also if you are goig to make libraries out of your files, why not using --shared option that will create a liked library. I find making shared libraries very useful.