Obviously something goes wrong with my understanding of this topic, but I can't find out where. The thing I want to implement is a custom Exception called CustomException. What I have made does compile and can work, but I do think that I am making use of header files the wrong way. So I have made the following 3 files:
main.cpp
#include "exception.h"
int main() {
try {
throw CustomException();
} catch (CustomException ce) {
ce.doSomething();
}
}
exception.h
#include <exception>
class CustomException : public std::exception {
private:
char* msg;
public:
CustomException() {};
void doSomething() {};
};
exception.cpp
#include "exception.h"
CustomException::CustomException() {
}
void CustomException::doSomething() {
printf("Hello World!");
}
After I run this is the command line:
$ g++ main.cpp -o main.o
$ ./main.o
$
But the behaviour that I was looking for is, that "Hello World!" is printed to the command line. I am more used to JAVA, so maybe that is why I have a rough start with C++. Anyways I hope you can help me, because the tutorials I found differ from each other and don't make sense to me.
Your problem is that you're defining CustomException::doSomething() to do nothing: {}. Leave out the {} method definitions in exception.h. Then compile and link exception.cpp into your binary:
$ g++ -c main.cpp -o main.o
$ g++ -c exception.cpp -o exception.o
$ g++ main.o exception.o -o main
$ ./main
Note that a ".o" suffix is normally used for object files, not for executables.
In addition to what user3553031 said, there is another posslble problem with your code. In C++ you should catch exceptions by reference, not by value. Otherwise it can cause problems. See this: C++ catch blocks - catch exception by value or reference?
Related
Following is a simplification of code from a larger project:
// foo.h
#ifndef FOO_H
#define FOO_H
#include <string>
class Foo
{
public:
Foo( const std::string& s = magic_ );
void func();
static const std::string magic_;
private:
std::string s_;
};
void func( const std::string& s = Foo::magic_ );
#endif
//foo.cpp
#include "foo.h"
#include <iostream
const std::string Foo::magic_ = "please";
Foo::Foo( const std::string& s )
: s_( s )
{ }
void Foo::func() { std::cout << "[" << s_ << "]" << std::endl; }
void func( const std::string& s )
{
Foo( s ).func();
}
// main.cpp
#include "foo.h"
int main( int argc, char* argv[] )
{
func();
return 0;
}
I'll call the above a MCE, not a MCVE because unfortunately I've not been able to reproduce the problem in a simplification, which I can only guess is because of quirks of static variables and shared linkage - possibly an incorrect assessment, because of a not-thorough understanding of what's involved. But I will try to explain the problem. The following aspects of the above MCE are representative of the problem code:
A header file declares a class with a static member std::string.
The same header defines a function with an in-arg defaulted to the class' static member variable.
The header's corresponding source file defines the static member and function.
The translation unit is compiled to a shared library.
The executable's object code is linked with the shared library.
Compilation/output:
$ g++ -O3 -c -fPIC -o ./foo.o ./foo.cpp
$ g++ -O3 -shared ./foo.o -o ./libfoo.so
$ g++ -O3 -c -fPIE -o ./main.o ./main.cpp
$ g++ -O3 ./main.o -o ./a.out -L./ -lfoo
$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH: ./a.out
[please]
Though not demonstrated above, is it a possibility that during executing the output may be "[]"? I.e. might Foo::magic_ be empty at the time used as the default value assigned to void func()'s in-arg?
This is hard to articulate in the absence of a demonstrable problem with the above MCE, but assuming it is truly representative of the problem code, I observe (by stdout due to gdb absence in the real build/test environment) that in void func(), in-arg s is an empty string - can anyone account for/explain why this could be?
I know initialization of static variables is not guaranteed across translation units - is that possibly involved here? (It seems like it might explain why the problem is not reproducible in an attempted simplification)
Again, apologies for the lack of a MCVE - I tried my best to create one.
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.
I'm trying to build a simple program where I defined a class and included it's header in Main. While linking, Linker complains about accessing any of the member function from class:
: undefined reference to voxel::anyFunction
even though functions are public and headers are included.
Originally I discovered the problem when creating an object of voxel - I had overloaded the default constructor, but I figure out the problem is present for any function from voxel class.
Here are some code excerpts:
voxel.hpp
class voxel
{
public:
//here defined some member variables
//ommited the constructor
void fillMemberValuesWithDummy();//sets all members to some dummy value
};
voxel.cpp
#include "voxel.hpp"
void voxel::fillMemberValuesWithDummy()
{
//does the assignment to member variables
}
Main.cpp
#include <iostream>
#include <fstream>
using namespace std;
#include "voxel.hpp"
{
voxel someVoxel;
somevoxel.fillMemberValuesWithDummy();
}
I figure it is something very stupid I am (not) doing here, but can you tell me what?
You need to link all object files to get the executable. When you have just your two source files you can compile them directly:
g++ -o myprog.exe Main.cpp voxel.cpp
When you want to divide compile and link and do it this way:
g++ -c -o Main.o Main.cpp
g++ -c -o voxel.o voxel.cpp
g++ -o myprog.exe Main.o voxel.o
Feel free to create an appropriate Makefile that generates such commands.
Remove the .exe if you OS doesn't need it.
Now when I try to compile main.cpp, I get an error as Undefined symbol add(int) in module main.cpp Please help me!
//main.cpp
#include<iostream.h>
#include "addition.h"
int main()
{
add(4);
return (0);
}
//add.cpp
#include "addition.h"
#include<iostream.h>
void add(int a)
{
cout<<a<<endl;
}
//addition.h
void add(int a);
The problem is that main() uses add(). And add is defined in another compilation unit (add.cpp) which is why you get the error message Undefined symbol add(int).
You need to tell the compiler to compile both pieces of code and link them together:
The easy way:
g++ main.cpp add.cpp
The long way:
# 1 Make the main object file
g++ -c main.cpp
# 2 Make the add object file
g++ -c add.cpp
# Link the object files into an executable.
g++ main.o add.o
Here is what I did, I want to gracefully handle this exception:
code_snippet: my.cpp
#include<iostream>
extern "C" void some_func()
{
throw "(Exception Thrown by some_func!!)";
}
code_snippet: exception.c
#include <stdio.h>
extern void some_func();
int so_main()
{
some_func();
return 0;
}
From above two snippets I have created a shared_object libexception.so by using following commands:
g++ -c -fPIC src/my.cpp
gcc -c -ansi -fPIC src/exception.c
g++ -fPIC -shared -o libexception.so
Then I called the function so_main from my main.cpp
code_snippet: main.cpp
#include<iostream>
#include <dlfcn.h>
using namespace std;
extern "C" void some_func();
int main()
{
int (*fptr)() = 0;
void *lib = dlopen("./libexception.so", RTLD_LAZY);
if (lib) {
*(void **)(&fptr) = dlsym(lib, "so_main");
try{
if(fptr) (*fptr)(); <-- problem lies here
//some_func(); <-- calling this directly won't crash
}
catch (char const* exception) {
cout<<"Caught exception :"<<exception<<endl;
}
}
return 0;
}
final command: g++ -g -ldl -o main.exe src/main.cpp -L lib/ -lexception
Executing main.exe crashes. Can somebody help me detect where the problem lies and how to avoid this crash to happen (We have already some architecture where some .SO calls extern c++ function, so that can't be changed, We want to handle it in main.cpp only)
Try compiling src/exception.c with -fexceptions
-fexceptions
Enable exception handling. Generates extra code needed to propagate exceptions. For some targets, this implies GNU CC will generate frame unwind information for all functions ...
However, you may need to enable this option when compiling C code that needs to interoperate properly with exception handlers written in C++. You may also wish to disable this option if you are compiling older C++ programs that don't use exception handling.
That function probably throws an exception that is not char* so you're not catching it.
try using a generalized catch:
*(void **)(&fptr) = dlsym(lib, "so_main");
try{
if(fptr) (*fptr)(); <-- problem lies here
//some_func(); <-- calling this directly won't crash
}
catch (char const* exception) {
cout<<"Caught exception :"<<exception<<endl;
}
catch (...) {
cout<<"Caught exception : Some other exception"
}