In the beginning I had:
main.cpp
#include "something.h"
#include "util.h"
int main() {
sth::something();
utl::little_thing();
}
somehing.h
#ifndef SOMETHING_H
#define SOMETHING_H
namespace sth {
void something();
}
#endif
somehing.cpp
#include "something.h"
#include <string>
#include <iostream>
namespace sth {
void print_me(std::string txt) {
std::cout << txt << std::endl;
}
void something() {
std::cout << "this is something" << std::endl;
print_me("optional");
}
}
util.h
#ifndef UTIL_H
#define UTIL_H
namespace utl {
void little_thing();
}
#endif
util.cpp
#include "util.h"
#include <iostream>
#include <string>
namespace utl {
void little_thing() {
std::cout << "this is little thing" << std::endl;
}
}
Then I though it will be better to have print_me(std::string txt) out of sth namespace. And I put it on utl, declaration on .h file and definition on .cpp file.
At that point the lazy side of me said - would it be better to have it all in one file as was beofore. And I tried:
util.h
#ifndef UTIL_H
#define UTIL_H
#include <string>
#include <iostream>
namespace utl {
void little_thing();
void print_me(std::string txt) {
std::cout << txt << std::endl;
}
}
#endif
something.cpp
#include "something.h"
#include "util.h"
#include <string>
#include <iostream>
namespace sth {
void something() {
std::cout << "this is something" << std::endl;
utl::print_me("optional");
}
}
So I got:
c++ -std=gnu++14 -g -Wall -O3 -c -o main.o main.cpp
c++ -std=gnu++14 -g -Wall -O3 -c -o util.o util.cpp
c++ -std=gnu++14 -g -Wall -O3 -c -o something.o something.cpp
c++ main.o util.o something.o -o main
duplicate symbol __ZN3utl8print_meENSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE in:
main.o
util.o
duplicate symbol __ZN3utl8print_meENSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE in:
main.o
something.o
ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main] Error 1
Which makes sense to me, since util.h is included in main.cpp and something.cpp there are duplicate symbols, right?
Question, is it possible to be as lazy to have it all in the header? Or no way, have to split decalration and definition? I don't care (in this case) to hide the implementation in the .cpp, I just want to move it out of sth.
Maybe move the definition of print_me down to util.cpp and only leave a declaration of it in the util.h file.
Else you get a copy of it in every object file, and then the linker gets confused as they all have the same name (symbol).
Related
please may you advise how I may compile & run main.cpp while compiling and linking the my_class.cpp & my_class.h class files,please note that this is running on an iPad using the “Code” app by “thebaselab”, which has offline clang++ 13.0. developer says its possible to work using the below method, however theres no output.
I compile seperately:
clang++ main.cpp -c
clang++ my_class.cpp - c
It seems to produce the main.o and my_class.o files so I may run using:
clang++ main.o my_class.o
This doesnt seem to run as no output, please may you advise if you can see the problem in my code or in compiling.?
I believe there is an issue with linking these files together, as when I have the class defined in main there’s no issues.
My code base:
main.cpp
// Created on iPad.
#include <iostream>
#include <vector>
#include "my_class.h"
using namespace std;
int main() {
cout << "Hey\n";
my_class obj1 = my_class("test");
obj1.display();
cout << "Hello World!";
return 0;
}
my_class.h
#ifndef _my_class_H_
#define _my_class_H_
class my_class
{
private:
std::string name = "";
public:
my_class(std::string name_tmp); // No-args constructor // Copy constructor
~my_class(); // Destructor
void display();
};
#endif
my_class.cpp
#include <iostream>
#include "my_class.h"
// 1-args constructor
my_class::my_class(std::string name_tmp){
name = name_tmp;
}
// Destructor
my_class::~my_class() {
std::cout << "Destructing\n";
}
void my_class::display(){
std::cout << name << "\n";
}
Thanks to #Quimby,
I ran clang++ -o a.out main.o my_class.o then just a.out and it works on my iPad.
I was trying to make a simple makefile to learn how to use headers and make in C++, however it doesn't seems to work, returning "undefined reference" at the end. What is going wrong here? I don't believe there are any mistakes in the .cpp or .hpp files, and I searched a bit about makefile to be sure that it should be working.
My main.cpp:
#include <iostream>
#include <fstream>
#include "test.hpp"
using namespace std;
int main(int argc, char *argv[]){
test::print();
return 0;
}
For test.hpp and test.cpp:
#include <iostream>
#include <fstream>
#pragma once
class test{
private:
public:
static void print();
};
#include <iostream>
#include <fstream>
#include "test.hpp"
using namespace std;
static void print(){
cout << "aaaaaa\n";
}
Finally, the makefile:
all:
rm *.o
g++ -c -g *.cpp
g++ *.o -o main.exe
rm *.o
I have the following 3 files, main.cpp and then a class defintion including a header file for the class:
main.cpp:
#include <iostream>
#include "data_vars_class.hpp"
int main () {
DataVars dataVars();
return 0;
}
data_vars_class.hpp:
#include <string>
#include <vector>
class DataVars
{
private:
std::vector<std::string> csv_card_names;
public:
DataVars();
void getCSVData();
};
data_vars_class.cpp:
#include <iostream>
#include <vector>
#include <string>
#include "data_vars_class.hpp"
DataVars::DataVars()
{
std::cout << "constructor?";
getCSVData();
}
void DataVars::getCSVData()
{
std::cout << "Getting csv data!";
}
The problem is when I build and execute the code, I just get an empty terminal. I know that both data_vars_class.hpp and data_vars_class.cpp are being included with the build, this is my build command in Geany:
g++ main.cpp data_vars_class.cpp -o a.out
How come i'm not seeing the cout output in the terminal, like in the constructor shouldnt i see "constructor?" in the terminal?
Thanks
by building the binary file gets created to run the code you have to write ./a.out in the terminal after building it.
g++ main.cpp data_vars_class.cpp -o a.out
./a.out
I have a small doubt in the compilation of a c++ code along with a shared library.
So I have two files main.cpp and sample.cpp.
main.cpp
#include <iostream>
using namespace std;
#include "sample.h"
myStruct obj;
void populateData() {
obj.s = "hello world";
}
myStruct giveData() {
cout << "Inside main: " << obj.s << endl;
return obj;
}
int main() {
populateData();
}
sample.h
#ifndef SAMPLE_H
#define SAMPLE_H
#include <string>
struct myStruct {
std::string s;
void populateData();
};
myStruct giveData();
#endif
sample.cpp
#include "sample.h"
#include <iostream>
#include <boost/python.hpp>
using namespace std;
void myStruct :: populateData() {
cout << giveData().s;
}
BOOST_PYTHON_MODULE(boosts) {
using namespace boost::python;
class_<myStruct>("struct")
.add_property("s", &myStruct::s)
.def("populateData", &myStruct::populateData)
;
}
I compile the program using
g++ -c -fPIC sample.cpp
g++ -c -fPIC main.cpp
g++ -shared -Wl,-soname,boosts.so -o boosts.so sample.o main.o -lpython2.7 -lboost_python
g++ -o main main.o
./main
Now, when I run the main, it populates the string inside the obj. But when I run a python script, that imports the boosts.so, the obj.s is empty.
I am guessing it is because the library boosts.so is not properly linked with the executable main.
How do I fix this?
objects = hello.o name.o printing.o
exename = himake
$(exename): $(objects)
$(CC) -o $(exename) $(objects)
%.o: %.cpp
$(CC) -c $^
I am trying to use common suffixes so I do not need to compile 3 files into .o first. This is supposed to do all three with the % wildcard.
It works fine when I do it the long way but not this.
Running the above makefile gives me this error below:
[alex#pcc Dir]$ make
cc -o himake hello.o name.o printing.o
hello.o: In function `__static_initialization_and_destruction_0(int, int)':
hello.cpp:(.text+0x23): undefined reference to `std::ios_base::Init::Init()'
hello.o: In function `__tcf_0':
hello.cpp:(.text+0x66): undefined reference to `std::ios_base::Init::~Init()'
and more that I did not include
Files:
hello.cpp:
// hello.cpp
// standard library
#include <iostream>
#include <string>
using namespace std;
// user defined header files
#include "name.h"
#include "printing.h"
int main ()
{
string name;
name = getName(); // getName is in name.h
printHello(name); // printHello is in print.h
return 0;
}
name.cpp
// name.cpp
// user defined header files
#include "name.h"
#include "printing.h"
string getName()
{
string name;
printGreeting(); // printGreeting is from print.h
getline(cin, name);
return name;
}
name.h
// name.h
#include <iostream>
using namespace std;
string getName();
printing.cpp
// printing.cpp
// user defined include files
#include "printing.h"
void printGreeting(void)
{
cout << "Your name: ";
return;
}
void printHello (string name)
{
cout << "Hi, " << name << endl;
return;
}
printing.h
// printing.h
#include <iostream>
using namespace std;
void printGreeting();
void printHello(string);
Because you use the C compiler frontend program, and not the C++ frontend program.
Change $(CC) to $(CXX).