Home > Software engineering >  Is it possible to call a function outside of main()?
Is it possible to call a function outside of main()?

Time:03-03

I guess my question is stupid, but nevertheless:

In my C code I use some legacy C library(XLib). In order to use this library a connection to X server has to be opened first:

::Display* const display = ::XOpenDisplay(nullptr);

This display structure is widely used across the vast majority of the XLib functions, including the functions for allocating and freeing memory and system resources such as fonts, colormaps etc. In my code I use objects' constructors and destructors to allocate and free resources by calling these functions. And here is the problem:

int main()
{
    ::Display* const display = ::XOpenDisplay(nullptr);
    // ...
    Object1 object1(display, ...); // uses display inside the destructor
    Object2 object2(display, ...); // uses display inside the destructor
    Object3 object3(display, ...); // uses display inside the destructor
    // ...
    ::XCloseDisplay(display); // invalidates the display structure
    return 0;
}

This example leads to segmentation fault, because the display structure had been invalidated by XCloseDisplay() before any of the destructors using it was called. To avoid this issue I can embrace all the code before XCloseDisplay() in curly braces to limit the scope of objects, but it makes the code to be shifted to right which looks pretty ugly.

Is there any way to somehow call XCloseDisplay() after the main()?

CodePudding user response:

It's possible, but unnecessary.

Instead, wrap it in a class that closes it in the destructor, like you did with the other objects.

Destructors are called in the reverse order, which means that if you create the display first, it'll die last.


The way you would've called it after main is, similarily, from a destructor of a global or function-local static object. A function-local static is better than a global variable because it avoids the static init order fiasco.

CodePudding user response:

use attribute with gcc also work as well

void __attribute__((constructor)) calledFirst();
void __attribute__((destructor)) calledLast();
  
void main()
{
    printf("\nI am in main");
}
  
// This function is assigned to execute before
// main using __attribute__((constructor))
void calledFirst()
{
    printf("\nI am called first");
}
  
// This function is assigned to execute after
// main using __attribute__((destructor))
void calledLast()
{
    printf("\nI am called last");
}

test: https://godbolt.org/z/vPhf36cbe

  • Related