'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