Reputation: 6285
I wanted to know if it was possible to call a void function without using a temp variable. E.g. in the following code block...
#include <iostream>
void earlyInit()
{
std::cout << "The void before the world." << std::endl;
}
int g_foo = (earlyInit(), 0);
int main( int argc, char* argv[] )
{
std::cout << "Hello, world!" << std::endl;
}
...I have no need for g_foo
and would rather it not exist. Is there a way to call void functions without an intermediate temp variable?
Upvotes: 1
Views: 1057
Reputation: 206667
I wanted to know if it was possible to call a void function without using a temp variable. E.g. in the following code block.
The language does not provide any such mechanism. As other answers have pointed out, there maybe compiler-specific ways to do that.
However, I don't see anything wrong with your approach. I use the following pattern a lot.
#include <iostream>
namespace mainNS // A file-specific namespace.
{
void earlyInit()
{
std::cout << "The void before the world." << std::endl;
}
struct Initializer
{
Initializer();
};
}
using namespace mainNS;
static Initializer initializer;
Initializer::Initializer()
{
earlyInit();
// Call any other functions that makes sense for your application.
}
int main( int argc, char* argv[] )
{
std::cout << "Hello, world!" << std::endl;
}
Upvotes: 2
Reputation: 6285
An answer to this question brought __attribute__((constructor))
to my attention, however, for reasons I don't fully understand, I observed a SIGSEGV
when using that if the void function used std::cout
(printf
did not cause the SIGSEGV
).
I posted a version of this question earlier (but stupidly deleted it). An answerer at that time pointed me to this excellent article which discusses the situation and solution:
http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html
Excerpt of the solution (modified slightly to pass compilation) is here:
#include <cstdio>
#include <cstdlib>
void preinit(int argc, char * * argv, char * * envp) {
printf("%s\n", __FUNCTION__);
}
void init(int argc, char * * argv, char * * envp) {
printf("%s\n", __FUNCTION__);
}
void fini() {
printf("%s\n", __FUNCTION__);
}
__attribute__((section(".init_array"))) typeof (init) * __init = init;
__attribute__((section(".preinit_array"))) typeof (preinit) * __preinit = preinit;
__attribute__((section(".fini_array"))) typeof (fini) * __fini = fini;
void __attribute__((constructor)) constructor() {
printf("%s\n", __FUNCTION__);
}
void __attribute__((destructor)) destructor() {
printf("%s\n", __FUNCTION__);
}
void my_atexit() {
printf("%s\n", __FUNCTION__);
}
void my_atexit2() {
printf("%s\n", __FUNCTION__);
}
int main() {
atexit(my_atexit);
atexit(my_atexit2);
}
(Apologies to the original answerer that I deleted my original post and can't give due credit.)
Upvotes: 0
Reputation: 597051
Check if your compiler supports #pragma startup
(or equivalent), eg:
#include <iostream>
void earlyInit()
{
std::cout << "The void before the world." << std::endl;
}
#pragma startup earlyInit
int main( int argc, char* argv[] )
{
std::cout << "Hello, world!" << std::endl;
}
Upvotes: 0