How to invoke a C++ function after main() finishes - c++

I am developing a C++ tool that should run transparent to main program. That is: if user simply links the tool to his program the tool will be activated. For that I need to invoke two functions, function a(), before main() gets control and function b() after main() finishes.
I can easily do the first by declaring a global variable in my program and have it initialize by return code of a(). i.e
int v = a() ;
but I cannot find a way to call b() after main() finishes?
Does any one can think of a way to do this?
The tool runs on windows, but I'd rather not use any OS specific calls.
Thank you, George

Use RAII, with a and b called in constructor/destructor.
class MyObj {
MyObj()
{
a();
};
~MyObj()
{
b();
};
};
Then just have an instance of MyObj outside the scope of main()
MyObj obj;
main()
{
...
}
Some things to note.
This is bog-standard C++ and will work on any platform
You can use this without changing ANY existing source code, simply by having your instance of MyObj in a separate compilation unit.
While it will run before and after main(), any other objects constructed outside main will also run at this time. And you have little control of the order
of your object's construction/destruction, among those others.

SOLUTION IN C:
have a look at atexit:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void bye(void)
{
printf("That was all, folks\n");
}
int main(void)
{
long a;
int i;
a = sysconf(_SC_ATEXIT_MAX);
printf("ATEXIT_MAX = %ld\n", a);
i = atexit(bye);
if (i != 0) {
fprintf(stderr, "cannot set exit function\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
http://linux.die.net/man/3/atexit
this still implies however that you have access to your main and you can add the atexit call. If you have no access to the main and you cannot add this function call I do not think there is any option.
EDIT:
SOLUTION IN C++:
as sudgested there is a c++ equivalent from std. I simply paste in here an example which i copied from the link available just below the code:
#include <iostream>
#include <cstdlib>
void atexit_handler_1()
{
std::cout << "at exit #1\n";
}
void atexit_handler_2()
{
std::cout << "at exit #2\n";
}
int main()
{
const int result_1 = std::atexit(atexit_handler_1);
const int result_2 = std::atexit(atexit_handler_2);
if ((result_1 != 0) or (result_2 != 0)) {
std::cerr << "Registration failed\n";
return EXIT_FAILURE;
}
std::cout << "returning from main\n";
return EXIT_SUCCESS;
}
http://en.cppreference.com/w/cpp/utility/program/atexit

Isn't any global variable constructed before main and destructed afterward? I made a test struct whose constructor is called before main and the destructor afterward.
#include <iostream>
struct Test
{
Test() { std::cout << "Before main..." << std::endl; }
~Test() { std::cout << "After main..." << std::endl; }
};
Test test;
int main()
{
std::cout << "Returning now..." << std::endl;
return 0;
}

If you're happy to stick with a single compiler and non-standard C/C++, then GCC's __attribute__((constructor)) and __attribute__((destructor)) might be of use:
#include <stdio.h>
void __attribute__((constructor)) ctor()
{
printf("Before main()\n");
}
void __attribute__((destructor)) dtor()
{
printf("After main()\n");
}
int main()
{
printf("main()\n");
return 0;
}
Result:
Before main()
main()
After main()

Alternatively to the destructor, you can use atexit() in a similar manner - in C++, you do not need to have access to main() to register atexit there. You can do that as well it in your a() - for example:
void b(void) {
std::cout << "Exiting.\n";
}
int a(void) {
std::cout << "Starting.\n";
atexit(b);
return 0;
}
// global in your module
int i = a();
That being said, I'd also prefer the global C++ class object, which will call the b() stuff in its destructor.

Related

segmentation fault while using pthreads in class

I have the follwing code that gets core dumped error. Each C instance creates their own thread then runs. I guess there is something wrong with static function and class argument "count". When I comment out the code that prints it, no fault occurs..
#include <iostream>
#include <pthread.h>
using namespace std;
class C {
public:
int count;
C(int c_): count(c_){}
public:
void *hello(void)
{
std::cout << "Hello, world!" <<std::endl;
std::cout<<count; // bug here!!!
return 0;
}
static void *hello_helper(void *context)
{
return ((C *)context)->hello();
}
void run() {
pthread_t t;
pthread_create(&t, NULL, &C::hello_helper, NULL);
}
};
int main() {
C c(2);
c.run();
C c2(4);
c2.run();
while(true);
return 0;
}
Decided to write an answer. You were calling hello_helper with a context of NULL based on how you were creating your thread. C++ fully allows you to call member functions on null pointers, and no error occurs unless a member element is accessed.
In your case, by adding the line to print count. You are now accessing a member variable on a null pointer, which is a big no-no.
Here's an example of what you were getting away with:
#include <iostream>
class Rebel
{
public:
void speak()
{
std::cout << "I DO WHAT I WANT!" << std::endl;
}
};
int main()
{
void * bad_bad_ptr = NULL;
((Rebel*)bad_bad_ptr)->speak();
}
Output:
I DO WHAT I WANT!
By modifying your pthread_create call to pass the this pointer (i.e. pthread_create(&t, NULL, &C::hello_helper, this);, you now have a valid instance to access member variables on.
I solved the problem by passing this pointer instead off NULL while creating threads. I guess os created same thread twice int the former case ?

Does std::future support polymorphism?

Does std::future in c++ support polymorphism?
So, if to store child_class in future<parent_class>, can I after get it after by dynamic_cast<child_class>?
Providing you use a reference or a pointer (probably obvious since it'll fail to compile otherwise)... Yes.
#include <iostream>
#include <future>
using namespace std;
struct Parent {
virtual void a() { cout << "I am parent"; }
};
struct Child : Parent {
virtual void a() { cout << "I am child"; }
};
Child g_c; //just some global for the purposes of the example
int main() {
std::future<Parent&> p = async(launch::async, []() -> Parent& { return g_c; });
auto c = dynamic_cast<Child&>(p.get());
c.a();
return 0;
}
code result here: http://ideone.com/4Qmjvc

How to catch an error resulting from an invalid memory block being destroyed

The following code makes it so that a destructor is called twice.
#include <iostream>
#include <memory>
#include <exception>
#include <cstdlib>
void myterminate()
{
std::cout << "terminate\n";
abort();
}
class data
{
int a;
public:
data(int a) : a(a) { std::cout << "ctor " << a << "\n"; }
~data() { std::cout << "dtor " << a << "\n"; }
static data failure(int a) { return data(a); }
};
void main()
{
std::set_terminate(myterminate); //terminate is not called
try
{
std::unique_ptr<data> u;
u.reset(&data::failure(1));
std::cout << "no worries\n"; //this prints
//destructor called at try-block end and attempt to destruct an invalid memory block.
}
catch (...)
{
std::cout << "caught\n"; //this can not catch the error
}
std::cout << "end\n"; //program crash, will not be called
}
How would I catch an error like this in production?
On a Release build the program crashes. On a Debug build it the on my system is:
How would I catch an error like this in production?
You cannot. The standard says that invalid memory access has undefined behaviour. There is no standard way to "catch" UB. Catching and terminate handler are for exceptions, which are defined behaviour.
What you could do, is use the debug build in production, and run it with valgrind or similar tool, so that you can at least analyze the error.
"try/catch" such mistakes will not catch, because in this case a great probability of a crash. But a moment of destruction you can try to catch, using signals and more menne dignified exit the program.
Looking away: #include , signal(), sig_atomic_t ...
First as noted in the comments you declare main as void main where the standard only allows two forms in § 3.6.1
An implementation shall not predefine the main function. This function
shall not be overloaded. It shall have a declared return type of type
int, but otherwise its type is implementation-defined. An
implementation shall allow both
(2.1) — a function of () returning int and
(2.2) — a function of (int, pointer to pointer to char) returning int
Secondly you are resetting your unique_ptr to manage a temporary which when unique_ptr gets destroyed at the end of its scope will be deleted which results in undefined behavior. You can't predict/catch errors resulting from undefined behavior.
What you should do (if you really want to use dynamically allocated memory) you can return a pointer to object on the heap:
#include <iostream>
#include <memory>
#include <exception>
#include <cstdlib>
void myterminate()
{
std::cout << "terminate\n";
abort();
}
class data
{
int a;
public:
data(int a) : a(a) { std::cout << "ctor " << a << "\n"; }
~data() { std::cout << "dtor " << a << "\n"; }
static data* failure(int a) { return new data(a); }
};
int main()
{
std::set_terminate(myterminate); //terminate is not called
try
{
std::unique_ptr<data> u;
u.reset(data::failure(1));
std::cout << "no worries\n"; //this prints
//destructor called at try-block end and attempt to destruct an invalid memory block.
}
catch (...)
{
std::cout << "caught\n"; //this can not catch the error
}
std::cout << "end\n"; //program crash, will not be called
}
Online code: http://melpon.org/wandbox/permlink/pdiijgDxBshVOYRu

destructor ignore string assignment

I have created a program in C++ for a class, and one of the requirements is to output a string when certain parts of the program have been called. For most of these I have simply assigned a string to a member variable and then outputted that variable. I wanted to know is it possible for me to assign the string in a destructor and then output that string? When I try it, it outputs nothing.
ie:
Class
private:
string output;
~Class {
output = "destructor has fired!";
}
int main(){
cout << class.message;
}
This is pseudocode so please ignore syntax mistakes/missing pieces.
It certainly is possible to output a message in the destructor, to know that it has fired, and one way to do it is this...
#include <iostream>
#include <string>
using namespace std;
class C{
string output; // by default private
public:
C(){}
~C() { cout << output << endl; }
void setString(const string& s) {
output = s;
}
};
int main()
{
{
C s;
s.setString("Destructor has fired");
}
return 0;
}
If I understand your question right, this is what you are expected to do. Note: no member variable, direct calls to std::cout.
#include <iostream>
#include <string>
using namespace std;
class C{
public:
C() {
cout << "C ctor" << endl;
}
~C() {
cout << "C dtor" << endl;
}
};
int main()
{
{
C s;
}
return 0;
}

"Warning: Can't find linker symbol for virtual table for value XXX value" using GCC and GDB (CodeBlocks)

I'm getting a runtime error ("memory can't be written") that, after inspection through the debugger, leads to the warning in the tittle.
The headers are the following:
componente.h:
#ifndef COMPONENTE_H
#define COMPONENTE_H
using namespace std;
class componente
{
int num_piezas;
int codigo;
char* proovedor;
public:
componente();
componente(int a, int b, const char* c);
virtual ~componente();
virtual void print();
};
#endif // COMPONENTE_H
complement.h implementation
#include "Componente.h"
#include <string.h>
#include <iostream>
componente::componente()
{
num_piezas = 0;
codigo = 0;
strcpy(proovedor, "");
//ctor
}
componente::componente(int a = 0, int b = 0, const char* c = "")
{
num_piezas = a;
codigo = b;
strcpy(proovedor, "");
}
componente::~componente()
{
delete proovedor;//dtor
}
void componente::print()
{
cout << "Proovedor: " << proovedor << endl;
cout << "Piezas: " << num_piezas << endl;
cout << "Codigo: " << codigo << endl;
}
teclado.h
#ifndef TECLADO_H
#define TECLADO_H
#include "Componente.h"
class teclado : public componente
{
int teclas;
public:
teclado();
teclado(int a, int b, int c, char* d);
virtual ~teclado();
void print();
};
#endif // TECLADO_H
teclado.h implementation
#include "teclado.h"
#include <iostream>
teclado::teclado() : componente()
{
teclas = 0;//ctor
}
teclado::~teclado()
{
teclas = 0;//dtor
}
teclado::teclado(int a = 0, int b = 0, int c = 0, char* d = "") : componente(a,b,d)
{
teclas = c;
}
void teclado::print()
{
cout << "Teclas: " << teclas << endl;
}
The main method where I get the runtime error is the following:
#include <iostream>
#include "teclado.h"
using namespace std;
int main()
{
componente a; // here I have the breakpoint where I check this warning
a.print();
return 0;
}
BUT, if instead of creating an "componente" object, I create a "teclado" object, I don't get the runtime error. I STILL get the warning during debugging, but the program behaves as expected:
#include <iostream>
#include "teclado.h"
using namespace std;
int main()
{
teclado a;
a.print();
return 0;
}
This returns "Teclas = 0" plus the "Press any key..." thing.
Do you have any idea why the linker is having troube with this? It doesn't show up when I invoke the virtual function, but before, during construction.
Two errors that I can see:
strcpy(proovedor, ""); // No memory has been allocated to `proovedor` and
// it is uninitialised.
As it is uninitialised this could be overwriting anywhere in the process memory, so could be corrupting the virtual table.
You could change this to (in both constructors):
proovedor = strdup("");
Destructor uses incorrect delete on proovedor:
delete proovedor; // should be delete[] proovedor
As this is C++ you should considering using std::string instead of char*.
If you do not change to std::string then you need to either:
Implement a copy constructor and assignment operator as the default versions are incorrect if you have a member variable that is dynamically allocated, or
Make the copy constructor and assignment operator private to make it impossible for them to be used.
Another source of this same message is that gdb can get confused by not-yet-initialized variables. (This answers the question title, but not the OP's question, since a web search led me here looking for an answer.)
Naturally, you shouldn't have uninitialized variables, but in my case gdb attempts to show function local variables even before they are declared/initialized.
Today I'm stepping through another developer's gtest case and this message was getting dumped to output every time the debugger stopped. In this case, the variable in question was declared on ~line 245, but the function started on ~line 202. Every time I stopped the debugger between these lines, I received the message.
I worked around the issue by moving the variable declaration to the top of the function.
For reference, I am testing with gdb version 7.11.1 in QtCreator 4.1.0 and I compiled with g++ version 5.4.1