'How to execute a piece of code only once?
I have an application which has several functions in it. Each function can be called many times based on user input. However I need to execute a small segment of the code within a function only once, initially when the application is launched. When this same function is called again at a later point of time, this particular piece of code must not be executed. The code is in VC++. Please tell me the most efficient way of handling this.
Solution 1:[1]
Use global static objects with constructors (which are called before main
)? Or just inside a routine
static bool initialized;
if (!initialized) {
initialized = true;
// do the initialization part
}
There are very few cases when this is not fast enough!
addenda
In multithreaded context this might not be enough:
You may also be interested in pthread_once or constructor
function __attribute__
of GCC.
With C++11, you may want std::call_once.
You may want to use <atomic>
and perhaps declare static volatile std::atomic_bool initialized;
(but you need to be careful) if your function can be called from several threads.
But these might not be available on your system; they are available on Linux!
Solution 2:[2]
Compact version using lambda function:
void foo()
{
static bool once = [](){
cout << "once" << endl;
return true;
} ();
cout << "foo" << endl;
}
Code within lambda function is executed only once, when the static variable is initialized to the return value of lambda function. It should be thread-safe as long as your compiler support thread-safe static initialization.
Solution 3:[3]
Using C++11 -- use the std::call_once
#include <mutex>
std::once_flag onceFlag;
{
....
std::call_once ( onceFlag, [ ]{ /* my code body here runs only once */ } );
....
}
Solution 4:[4]
You can use local static variable:
void foo()
{
static bool wasExecuted = false;
if (wasExecuted)
return;
wasExecuted = true;
...
}
Solution 5:[5]
Additionally to @Basile's answer, you can use a lambda to encapsulate the static variable as follows:
if ([] {
static bool is_first_time = true;
auto was_first_time = is_first_time;
is_first_time = false;
return was_first_time; } ())
{
// do the initialization part
}
This makes it easy to convert into a general-purpose macro:
#define FIRST_TIME_HERE ([] { \
static bool is_first_time = true; \
auto was_first_time = is_first_time; \
is_first_time = false; \
return was_first_time; } ())
Which can be placed anywhere you want call-by-need:
if (FIRST_TIME_HERE) {
// do the initialization part
}
And for good measure, atomics shorten the expression and make it thread-safe:
#include <atomic>
#define FIRST_TIME_HERE ([] { \
static std::atomic<bool> first_time(true); \
return first_time.exchange(false); } ())
Solution 6:[6]
could you do this
have a function that return a bool or some datatype called init
I made it happen this way, you need static bool to make it happens
bool init()
{
cout << "Once " <<endl;
return true||false;// value isn't matter
}
void functionCall()
{
static bool somebool = init(); // this line get executed once
cout << "process " <<endl;
}
int main(int argc, char *argv[])
{
functionCall();
functionCall();
functionCall();
return EXIT_SUCCESS;
}
for C
#include <stdio.h>
void init()
{
printf("init\n");
}
void process()
{
static int someint = 0;
if(someint == 0)
{
someint = 1;
init();
}
printf("process\n");
}
int main()
{
process();
process();
process();
return 0;
}
Solution 7:[7]
std::call_once()
et al. may be overkill if you don't need a totally thread-safe solution.
If not, we can make this look especially elegant when using C++17's initialisation-within-if
and std::exchange()
:
#include <utility>
void
do_something_expensive_once()
{
if ( static auto called = false; !std::exchange(called, true) ) {
do_something_expensive();
}
}
If this is a pattern you use a lot, then we can encapsulate it via a tag type:
#include <iostream>
#include <utility>
template <typename T>
auto
call_once()
{
static auto called = false;
return !std::exchange(called, true);
}
void
do_something_expensive()
{
std::cout << "something expensive\n";
}
void
do_something_expensive_once()
{
if ( call_once<struct TagForSomethingExpensive>() ) {
do_something_expensive();
}
}
auto
main() -> int
{
for (auto i = 0; i < 5; ++i) {
do_something_expensive_once();
}
return 0;
}
This will only print something expensive
a single time. Result! It also uses the ability to declare a tag struct
in a template argument list, for maximal brevity.
Alternatively, you could template on a function's address, a unique integer, etc.
You can then also pass a callable to call_once()
, and so on, and so forth. As usual for C++: the possibilities are endless!
Solution 8:[8]
Another simple solution is:
#define execute_once if(static bool b = false; b) ; else if((b = true))
Used thus:
execute_once std::cout << "Hi mum!\n";
or:
execute_once
{
std::cout << "These statements are ";
std::cout << "only executed once\n";
}
It's not thread safe, obviously. (EDIT: although just using a std::atomic_bool in place of the bool would get you there I think.)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Alexis Wilke |
Solution 3 | BeeOnRope |
Solution 4 | Abyx |
Solution 5 | John McFarlane |
Solution 6 | |
Solution 7 | |
Solution 8 |