Helper functions

K

Koen

Hi all,

I have a question about something rather common, but I'm a bit lost at
the moment:

Lat's say you have this:

// in A.h
Class A
{
public:
A();
~A();
void DoIt(bool inSpecial);
}

where the DoIt function should do something different depending on the
given bool:

// in A.cpp
void A::DoIt(bool inSpecial)
{
if (inSpecial)
DoItNormal();
else
DoItSpecial();
}

and the DoIt... functions do not need access to the class.

You can now implement the two DoIt... functions in several ways:

1. make them private member functions of the class:
This is not strictly necessary, since they do not access class data.
But users of the class will see the two helper functions in the A.h
header (which is something I'd like to avoid).

2. put them in the A.cpp file:
This way, these functions will become global functions, which is
something I'd like to avoid.

3. put them in the A.cpp file with the "static" keyword:
This way, they will only be visible at file-scope.

I'd think 3. would be the nicest solution, but what about thread safety?
If these two functions do rather lengthy calculations and they are
called from multiple threads, couldn't that lead to problems (storage
used in the static function accessed from two threads)? Is this less of
a problem if you're using approach 1. (private member functions)? I
think not, right?

Koen
 
I

Ivan Vecerina

Hi,
I have a question about something rather common, but I'm a bit lost at
the moment:

Lat's say you have this:

// in A.h
Class A
{
public:
A();
~A();
void DoIt(bool inSpecial);
}

where the DoIt function should do something different depending on the
given bool:

// in A.cpp
void A::DoIt(bool inSpecial)
{
if (inSpecial)
DoItNormal();
else
DoItSpecial();
}

and the DoIt... functions do not need access to the class.
NB: then DoIt(bool) itself could be declared as a static member
of class A.
You can now implement the two DoIt... functions in several ways:

1. make them private member functions of the class:
This is not strictly necessary, since they do not access class data.
But users of the class will see the two helper functions in the A.h
header (which is something I'd like to avoid). Agreed.

2. put them in the A.cpp file:
This way, these functions will become global functions, which is
something I'd like to avoid.
Note that you can put the two functions in an anonymous namespace,
which will 'hide' them from other translation units:
namespace {

void f() // will be hidden from the outside
{ ..... }

}
3. put them in the A.cpp file with the "static" keyword:
This way, they will only be visible at file-scope.

I'd think 3. would be the nicest solution, but what about thread safety?
In terms of thread safety, there is absolutely no difference between
static or non-static global functions. (This is not to be confused with
static variables declared in function scope, which may have issues).
If these two functions do rather lengthy calculations and they are
called from multiple threads, couldn't that lead to problems (storage
used in the static function accessed from two threads)? Is this less of
a problem if you're using approach 1. (private member functions)? I
think not, right?
It is absolutely the same. Function-scope variables in a static function
are not using static variable storage -- unless specified explicitly.
Local variables are still stack-based (using automatic storage) by default.

So the correct approach is either #2(with anonymous namespace), or #3.
Note that static functions have some limitations when using templates,
so the C++ standard has deprecated static functions (#3). But if the
template issue does not affect you, #3 is a perfectly ok and valid choice.


Cheers,
Ivan
 
V

Victor Bazarov

Koen said:
I have a question about something rather common, but I'm a bit lost at
the moment:

Lat's say you have this:

// in A.h
Class A
{
public:
A();
~A();
void DoIt(bool inSpecial);
}

where the DoIt function should do something different depending on the
given bool:

// in A.cpp
void A::DoIt(bool inSpecial)
{
if (inSpecial)
DoItNormal();
else
DoItSpecial();
}

and the DoIt... functions do not need access to the class.

You can now implement the two DoIt... functions in several ways:

1. make them private member functions of the class:
This is not strictly necessary, since they do not access class data.
But users of the class will see the two helper functions in the A.h
header (which is something I'd like to avoid).

2. put them in the A.cpp file:
This way, these functions will become global functions, which is
something I'd like to avoid.

3. put them in the A.cpp file with the "static" keyword:
This way, they will only be visible at file-scope.

4. Same as 3, but don't declare them 'static' and instead put them in
the anonymous namespace. This is the preferred method.
I'd think 3. would be the nicest solution, but what about thread safety?

C++ has no concept of a "thread". That usually means that nothing is
"thread-safe" unless you make it such.
If these two functions do rather lengthy calculations and they are
called from multiple threads, couldn't that lead to problems (storage
used in the static function accessed from two threads)?

It definitely could especially if they use shared data. If they don't
use shared data, what problems do you see?
Is this less of
a problem if you're using approach 1. (private member functions)? I
think not, right?

AFAIK, "thread safety" is completely orthogonal to membership or linkage.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top