How modularization is working in c++ - c++

Currently, I'm learning c++ and a question about the modularization process. Suppose I want to write a function to add two or three numbers. For that purpose I've wrote the following header file:
// Sum2.hpp
//
// Preprocessor directives; ensures that we do not include a file twice
// (gives compiler error if you do so)
#ifndef Sum2_HPP
#define Sum2_HPP
/////////// Useful functions //////////////////
// Max and Min of two numbers
double Sum2(double x, double y);
// Max and Min of three numbers
double Sum2(double x, double y, double z);
////////////////////////////////////////////////
#endif
This is just declaration. In a separate file, I specify the functions:
// Sum2.cpp
// Code file containing bodies of functions
//
#include "Sum2.hpp"
/////////// Useful functions //////////////////
// Sum of two numbers
double Sum2(double x, double y)
{
return x+y;
}
// Sum of three numbers
double Sum2(double x, double y, double z)
{
return Sum2(Sum2(x,y),z);
}
And then, in the main programm I want to use these functions:
// main.cpp
#include <iostream>
#include "Sum2.hpp"
int main()
{
double d1;
double d2;
double d3;
std::cout<<"Give the first number ";
std::cin>> d1;
std::cout<<"Give the second number ";
std::cin>> d2;
std::cout<<"Give the third number ";
std::cin>> d3;
std::cout<<"The sum is: "<<Sum2(d1,d2);
std::cout<<"The sum is: "<<Sum2(d1,d2,d3);
return 0;
}
I used g++ -c Sum2.cpp to generate the object code Sum2.o. Why is there a reference error when I want to compile and create an executable from the main code, i.e. g++ -o main main.cpp?
It is working when I compile both at same time, i.e. g++ -o main main.cpp Sum2.cpp. I thought by creating the object code Sum2.o and including the header file in main.cpp the compiler will automatically recognize the object code. Why this is not working?

// Preprocessor directives; ensures that we do not include a file twice
// (gives compiler error if you do so)
No actually, it won't give a compiler error. It just won't do anything.
As for your actual question, c++ unlike some other languages won't try to find your object files for you. You have to tell the compiler where they are at. For this application you should really compile it like so:
g++ -c main.cpp
g++ -c Sum2.cpp
g++ -o main main.o Sum2.o
The first two actually compile the code. The second links the code together to produce the executable. If you execute
g++ -o main main.cpp Sum2.cpp
The compiler will automatically run both steps for you. It works for a small project, but for larger projects you don't want to run all the steps unless something has changed.
Now, you may think that's a pain. You'd be right. That's why there are various tools like CMake, Scons, Jam, Boost.Build which are designed to make it easier to build C++ projects.

Related

How can I undo compilation of a file overwriting another file?

I was trying to compile my c++ program using the command g++ program.cpp -o program in order to create an executable with the same name as the actual program but used g++ program.cpp -o program.cpp and now my code looks like gibberish. Is there anyway to reverse it?
Reversing this process is semi-possible, but I do not recommend it. It is easier to just rewrite the program, as the compilation loses a ton of info. If you had compiled it with -g I believe it would be possible to recover the source (I have no idea though how one would do that).
If you have to reverse it you need to use a decompiler such as Cutter/Ghidra, but the result will need to be cleaned up. Example:
#inlcude <iostream>
#include <string>
int main(){
std::string a = "Hey";
a += '\n';
std::cout << a;
return 0;
}
Compiling with g++ test.cc -o test, and then decompiling with Ghidra, gets us:
undefined8 main(void){
long in_FS_OFFSET;
allocator<char> local_49;
basic_string<char,std::char_traits<char>,std::allocator<char>> local_48 [40];
long local_20;
local_20 = *(long *)(in_FS_OFFSET + 0x28);
std::allocator<char>::allocator();
/* try { // try from 001012a3 to 001012a7 has its CatchHandler # 001012fc */
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string
((char *)local_48,(allocator *)&DAT_00102005);
std::allocator<char>::~allocator(&local_49);
/* try { // try from 001012c2 to 001012d9 has its CatchHandler # 0010131a */
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator+=
(local_48,"\n");
std::operator<<((basic_ostream *)std::cout,(basic_string *)local_48);
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string
(local_48);
if (local_20 != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 0;
}
Pretty far gone, huh. The original program was only a few lines, but this seems a monstrosity. By knowing what to look for you can ignore things the compiler placed there to be safe like __stack_chk_fail(), and the anything that has in_FS_OFFSET or local_20 in it. But it is extremely laboursome in general. With some code it might be easier, but parts of it might be optimised away etc. so it is generally not recommended.
Note: I did not paste it here but at DAT_00102005, the string "Hey" is contained.

Problems linking static library to c++ project with MinGW

Edit: ***Sorry I realize there must have been some misunderstanding when posting this question, I want to specify that I DO realize this question was asked a few times, none of the answers work for me however***
I've been trying to link a simple static library test to one of my c++ projects, but I can't seem to get it quite right. I know that this is a very widespread topic and that a lot of people have already asked a similar question, but even after reading some of the answers, I still cannot, for the love of god, figure out what I am doing wrong.
My code is very simple, first I have a .cpp source file titled "Math.cpp" that looks like this:
#include "Math.h"
int max(int a, int b) {
return a > b ? a : b;
}
int min(int a, int b) {
return a < b ? a : b;
}
int floor(double a) {
return (int) a;
}
int ceil(double a) {
return (int) a + 1;
}
..And to go with that I made a header file called "Math.h" that looks like this:
#pragma once
int max(int, int);
int min(int, int);
int floor(double);
int ceil(double);
I then compile "Math.cpp" with the following command on cmd:
g++ -c Math.cpp -o Math.o
...and then compile it into a static library like so:
ar rcs libMath.a Math.o
After all of this I make a new c++ soure file titled "Main.cpp" that looks like this:
#include <iostream>
#include "Math.h"
int main() {
std::cout << max(9, 8) << std::endl;
return 0;
}
("Math.h" is in the same directory as "Main.cpp")
So finally in order to link "Main.cpp" with my static library ("libMath.a"), I use the following command in cmd:
g++ -o Main.exe Main.cpp -L. -lMath
however, at this point, it throws the following error:
C:\Users\zalmar\AppData\Local\Temp\ccmOnvyg.o:Main.cpp:(.text+0x18): undefined reference to `max(int, int)'
collect2.exe: error: ld returned 1 exit status
... I cannot figure out why it can't find the reference to the specific function. Some people appeared to have the same problem (here for example). Their solution was to declare the Main.cpp source file before declaring the library path. However, that was not the case for me, even though I made sure I was linking the library after the Main.cpp it still came up with the same error. I would greatly appreciate it if someone could point out anything I might be doing wrong because clearly I must be doing something wrong. Otherwise it might be a problem with my MinGW compiler, maybe?
I also want to re-mention that this is just a test library and I am fully aware that it might be a bit overkill to compile an entire static library from such a simple program. I am simply trying to figure out how to link libraries to my c++ projects...

Singleton across compilation units: linking library vs linking objects

I apologize if the title is not fully self-explanatory. I'm trying to understand why my singleton factory pattern is not working properly, and I ran into a bizarre difference when using library vs linking single objects files.
Here's a simplified version of the code:
main.cpp
#include <iostream>
#include "bar.hpp"
int main (int /*argc*/, char** /*argv*/)
{
A::get().print();
return 0;
}
bar.hpp
#ifndef BAR_HPP
#define BAR_HPP
#include <iostream>
class A
{
public:
static A& get ()
{
static A a;
return a;
}
bool set(const int i)
{
m_i = i;
print();
return true;
}
void print ()
{
std::cout << "print: " << m_i << "\n";
}
private:
int m_i;
A () : m_i(0) {}
};
#endif // BAR_HPP
baz.hpp
#ifndef BAZ_HPP
#define BAZ_HPP
#include "bar.hpp"
namespace
{
static bool check = A::get().set(2);
}
#endif // BAZ_HPP
baz.cpp
#include "baz.hpp"
Now, I build my "project" in two ways:
Makefile:
all:
g++ -std=c++11 -c baz.cpp
g++ -std=c++11 -o test main.cpp baz.o
lib:
g++ -std=c++11 -c baz.cpp
ar rvs mylib.a baz.o
g++ -std=c++11 -o test main.cpp mylib.a
Here are the outputs I get:
$ make all
$ ./test
print: 2
print: 2
$ make lib
$ ./test
print: 0
In the first case the call to A::get().set(2) in baz.hpp takes place, and the same instantiation of A is then used in the main function, which therefore prints 2. In the second case, the call to A::get().set(2) in baz.hpp never takes place, and in the main function the value set by the constructor (that is, 0) is printed.
So finally I can ask my question: why is the behavior different in the two cases? I would expect that either both print 0 once or print 2 twice. I always assumed that a library was just a compact way to ship object files, and that the behavior of linking mylib.a should be the same as that of linking baz.o directly. Why isn't that the case?
Edit: the reason, as explained by Richard, is that no symbols defined in baz.cpp are required in main.cpp, so baz.o is not extracted from the library and linked. This raises another question: is there a workaround to ensure that the instruction A::get().set(2) is executed? I would like to avoid making the singleton a global object, but I'm not sure it's possible. I would also like to avoid to include baz.hpp in the main, since there may be many bazxyz.hpp and that would require main.cpp to know in advance all of them, defying the whole purpose of the factory-like registration process...
If this is to be a static library, then some module somewhere is going to have to address something in each implementation file of the objects that are going to register themselves with the factory.
A reasonable place for this would be in bar.cpp (which is a file you don't yet have). It would contain some or all of the implementation of A plus some means of calling the registration functions the widgets you're going to create.
Self-discovery only works if the object files are linked into the executable. This gives the c++ startup sequence a chance to know about and construct all objects with global linkage.

(avoid) splitting code to .cpp and .h in C++ and efficient compilation

The common practice in C++ is to separate declarations in .h (or .hpp) and implementation into .cpp.
I know about two main reasons ( maybe there are others ):
Compilations speed ( you do not have to recomplie everything when you change just one file, you can link it by make from pre-compiled .o files )
Forward declarations are sometimes necessary ( when implementation of class A depends on class B and implementation of class B on class A ) ... but I don't have this problem so often and usulaly I can solve it.
In case of object oriented programming it looks like this:
QuadraticFunction.h:
class QuadraticFunc{
public:
double a,b,c;
double eval ( double x );
double solve( double y, double &x1, double &x2 );
};
QuadraticFunction.cpp:
#include <math.h>
#include "QuadraticFunc.h"
double QuadraticFunc::eval ( double x ){ return c + x * (b + x * a ); };
double QuadraticFunc::solve( double y, double &x1, double &x2 ){
double c_ = c - y;
double D2 = b * b - 4 * a * c_;
if( D2 > 0 ){
double D = sqrt( D2 );
double frac = 0.5/a;
x1 = (-b-D)*frac;
x2 = (-b+D)*frac;
}else{ x1 = NAN; x2 = NAN; }
};
main.cpp :
#include <math.h>
#include <stdio.h>
#include "QuadraticFunc.h"
QuadraticFunc * myFunc;
int main( int argc, char* args[] ){
myFunc = new QuadraticFunc();
myFunc->a = 1.0d; myFunc->b = -1.0d; myFunc->c = -1.0d;
double x1,x2;
myFunc->solve( 10.0d, x1, x2 );
printf( "soulution %20.10f %20.10f \n", x1, x2 );
double y1,y2;
y1 = myFunc->eval( x1 );
y2 = myFunc->eval( x2 );
printf( "check %20.10f %20.10f \n", y1, y2 );
delete myFunc;
}
then compile it with makefile like this:
FLAGS = -std=c++11 -Og -g -w
SRCS = QuadraticFunc.cpp main.cpp
OBJS = $(subst .cpp,.o,$(SRCS))
all: $(OBJS)
g++ $(OBJS) $(LFLAGS) -o program.x
main.o: main.cpp QuadraticFunc.h
g++ $(LFLAGS) -c main.cpp
QuadraticFunc.o: QuadraticFunc.cpp QuadraticFunc.h
g++ $(LFLAGS) -c QuadraticFunc.cpp
clean:
rm -f *.o *.x
However, I find it often very inconvenient
especially, when you change code a lot ( e.g. in initial phase of development when you are not yet sure about overall structure of the whole project ).
You have to go back-and-forth all the time between .cpp and .h part of code when doing significant changes to the class structure.
You have twice as much files in the editor and in project folder which is confusing.
You have to write some informations ( like function headers or QuadraticFunc:: ) twice, where you can do many typos and inconsistencies so the compiler complains all the time ( I do such mistakes very often )
Every-time you add / remove / rename some class you have to edit Makefile, where you do a lot of other mistakes which are hard to track from the compiler output ( e.g. I often forgot to write Makefile so that the code recompiles every dependency which I edit )
From this point of view I like much more how Java works. For this reason I was writing my C++ programs simply by putting all the code (including implementation) inside .h. Like this:
#include <math.h>
class QuadraticFunc{
public:
double a,b,c;
double eval ( double x ){ return c + x * (b + x * a ); }
double solve( double y, double &x1, double &x2 ){
double c_ = c - y;
double D2 = b * b - 4 * a * c_;
if( D2 > 0 ){
double D = sqrt( D2 );
double frac = 0.5/a;
x1 = (-b-D)*frac;
x2 = (-b+D)*frac;
}else{ x1 = NAN; x2 = NAN; }
};
};
with universal default makefile like this:
FLAGS = -std=c++11 -Og -g -w
all : $(OBJS)
g++ main.cpp $(LFLAGS) -w -o program.x
( main.cpp remains the same )
However, now when I'm starting to write more complex programs, the compile time starts to be quite long when I have to recompile everything all the time.
Is there any way how to use advantages of make ( faster compile time ) and still organize program structure in the Java-like way ( everything in class body instead of separate .h and .cpp ) which I find much more convenient ?
However, now when I'm starting to write more complex programs, the compile time starts to be quite long when I have to recompile everything all the time.
One of the best points in separating header and the class file is that you don't have to compile everything.
When you have class1.h, class1.cpp, class2.h, class2.cpp, ... ,classN.h and classN.cpp, those headers are only included in the compiled objects of each class. So if your function's logic changes in class2 but your header doesn't, you'll only have to compile class2 into object file. Then you'll do the linking for all object files which produces your actual executable. Linking is FAST.
If you are building large and complex programs and find that editing the headers is the problem, consider DESIGNING your application before writing it.
Short answer: no.
Long answer: Still no.
Either you put all your code in a header file, or you use two files, where the header is included and the source file compiled on its own.
I personally have no problem with using two files. Most editors support a "two file view" - and most of them also support "jump to definition of ".
Putting all functions inside the class declaration also has another side-effect, and that is that all functions are marked inline, which can lead to the function being produced multiple times in the output binaries if the same header is included in several source files.
Although the compile time, in my experience, is not a consequence of parsing, but of the code-generation part of the compilation - which typically is the .cpp file - so if you include several large headers most likely won't matter that much.
Of course use make [or something similar] with properly defined dependencies to build your project.
C++ is C++ and Java is Java. Splitting your source code in .h- und .cpp files is part of C++'s language concept. If you don't like it you shouldn't use it.
Putting everything in one header-file is practially the same as including the .cpp file (which works but is highly inappropriate).
You should not do this when:
writing standard classes, functions,...
using the code section multiple times in bigger programs (leads to redefinition error when you include everything in main.cpp otherwise)
you want to outsource part of your program in a static/dynamic library. Pretty much every available library created works that way.
Examples: WindowsAPI (COM!!), SFML, Boost (partly) (and a lot more)
You could do this when:
the code does very simple things, e.g. Bit-shift operation (making color codes), string analysis,...
Examples: Boost (partly)
You must do this when:
Creating template classes or functions as they are generated at compiling runtime. This is one of the major and most discussed downsides on the .h/.ccp-concept, so you are not the first one to wonder about it.
Examples: STL (C++ standard template library)
First of all you have to write implementation and definition in seperated file because of readebility. İt is possible to put them into same file , but it is not readable . When writing code, write for the next contributor who will need to understand your code. That is important because the next one may be you :) Second issue is makefile . Make is to make easier compilation process not faster . So if you make change in any of your file, you don't need to make change ant make files. Thanks of make , you dont need to compile your file in order again and again.write the files once , use every time. But if you add new code file which effect compilation process ,yes you have to make change in makefile. You can more information about readability,writing definition and implementation in seperate files and the all other style issue in google c++ style guide and about makefile in gnu make manuel.

kcachegrind: there is no source available for the following function

I am trying to view the annotated source using $ valgrind --tool=callgrind ./myProgram followed by $ kcachegrind using Ubuntu 12.04 (and I'm having the same problem with $ qcachegrind using Mac OSX).
The C++ script myProgram.cpp makes calls to functions that live in a .hpp file (via #include "../include/myHeader.hpp", etc.). I compile myProgram.cpp like this:
g++ -g -o myProgram myProgram.o -l<some third party lib>
where I don't care about viewing annotated source for that third party lib.
What I would like to see is annotated source for the functions in myHeader.hpp and for myProgram.cpp.
Instead, I see kcachegrind's Flat Profile window with a list of all the functions that get called, including the functions in myHeader.hpp - this is great. Now, kcachegrind reports the location of functions from myHeader.hpp as being from myProgram - this is odd. And finally, when I select any function from the Flat Profile window and request to see Source Code, I am met with:
There is no source available for the following function
<name of the selected function>
This is because no debug information is present.
Recompile the source and redo the profile run.
The function is located in the ELF object:
<some location...>
What I've tried:
added the directory holding myHeader.hpp to the Annotations list using kcachegrind's GUI.
compiled using -O0 to remove compiler optimizations
I'm answering my own question thanks to user n.m. - I discovered this while running a simplified example. The problem was with my compilation instruction, I was compiling to an object file with -g rather than compiling to an executable with -g.
Here's a working example for how to get kcachegrind to show annotated source:
main.cpp lives in directory someDirectory/example
// main.cpp
#include <iostream>
#include <math.h>
#include "../include/header.hpp"
using namespace std;
int main() {
double a=1.0; double b=4.0;
double tol = 1E-10;
double zero = -99;
if (sin(a)*sin(b) < 0 && (b-a) >= tol)
zero = bisect_sine(a,b,tol);
cout << zero << endl;
return 0;
}
Header file header.hpp lives in someDirectory/include
// header.hpp
#include <math.h>
#include <iostream>
using namespace std;
double bisect_sine(double a, double b, double tol) {
double c;
int step = 0; int maxsteps = 100;
while (step < maxsteps) {
c = (a+b)/2.0;
if (sin(c) == 0 || (b-a)/2 < tol)
return c;
if (sin(a)*sin(c) >= 0)
a = c;
else
b = c;
step+=1;
}
}
Makefile
# Makefile
CXX = g++
main:
$(CXX) -g -o main main.cpp
chmod 700 main
clean:
rm main
After all of this, simply run make (yielding the executable main that was compiled with debugging -g), followed by valgrind --tool=callgrind ./main. This will produce the expected callgrind.out.<PID> file, which can be read by kcachegrind. Source annotation will then be available for the main() function of main.cpp as well as for bisect_sine() from the header file.
So, this turned out to be a compilation issue. If I understood more about compilation into executables, object files, shared objects, yada yada yada, I would not have gotten into this mess.