using local static variable inside a function

S

subramanian100in

Is it advisable to use a local static variable inside a function ? I
want to know whether there are any drawbacks of using local static
variable inside a function.

Kindly explain.

Thanks
V.Subramanian
 
V

Victor Bazarov

Is it advisable to use a local static variable inside a function ?

Yes. No. Maybe.
> I
want to know whether there are any drawbacks of using local static
variable inside a function.

Drawbacks? I am not sure I understand the question. A static variable
is what it is - a static variable. Its use has the same drawbacks as
with any other static variable. But why would you think of the
drawbacks beforehand? Use what's needed. If you need a static
variable, use it. If you don't need a static variable, don't use it.

V
 
A

AnonMail2005

Is it advisable to use a local static variable inside a function ? I
want to know whether there are any drawbacks of using local static
variable inside a function.

Kindly explain.

Thanks
V.Subramanian

A static variable inside a function can sometimes be a good idea. A
Meyers singleton is a good example of the use of a static variable
inside a function.

But, and this is a big one, once you move from single threaded apps,
any static variables inside a function run into initialization issues
if more than one thread calls the function.

Static variable inside a function have compiler generated code that
makes sure the object is only constructed and initialized once. Since
standard C++ knows nothing about threads, the mechanism used to ensure
this is not thread safe.

HTH
 
M

Michael Doubez

A static variable inside a function can sometimes be a good idea.  A
Meyers singleton is a good example of the use of a static variable
inside a function.

I would not call it a good idea. It is a patch on the initialisation
order issue. Which, as an example doesn't exists in C, because nothing
executes before main().

A good visible comment: "don't call this function before main" and
using a classical static variable initialised before entering main is
far better but not always practical.

As said Victor Bazarov, I you need to use a static variable then use
one and if not don't. Once you have determined you need one then
handle the forces it brings.

IMHO using a static is more a choice you are forced into than a free
design issue.
 
S

SG

Sorry, but that's a copout. If a compiler supports multiple threads,
then it should provide a thread-safe mechanism for initializing
function-static data objects. If it doesn't, don't blame the standard.
Blame the compiler.

If it doesn't it might still be a standards compliant compiler. I
think this was AnonMail's point.

Can you clarify what it means to "support multiple threads"?

Cheers,
SG
 
N

Noah Roberts

Is it advisable to use a local static variable inside a function ? I
want to know whether there are any drawbacks of using local static
variable inside a function.

They aren't thread safe.

They are often used when they're not needed and can make otherwise
simple problems difficult.
 
P

Paul N

Is it advisable to use a local static variable inside a function ? I
want to know whether there are any drawbacks of using local static
variable inside a function.

You can get nasty results if you forget what you're doing. For
instance, suppose you have a function that returns a string - say, the
date, or time, or a formatted version of several inputs. To save
allocating, you have a static array of char in the function. Things
can go wrong if you call the function twice without copying the
result. For example:

char *formatted_time(void) {
static char buff[20];
// load up buff with, eg, "22:16"
return buff;
}

....
char *before, *after;

before = formatted_time();
// do stuff
after = formatted_time();
if (strcmp(before, after) == 0) printf("Why did it take no time?");

The problem here is that before and after are both pointers into the
same buffer so have the same values and the same contents.

Hope that helps.
Paul.
 
J

James Kanze

They aren't thread safe.

That depends on how they are used.

But I think you mean that their initialization isn't inherently
thread safe. Except that as Pete Becker points out, that's not
really the case---the standard, of course, doesn't say anything,
but from a QoI point of view, if the compiler supports threading
otherwise, it should also arrange for the initialization to be
thread safe. (Of course, from this point of view, there are a
lot of compilers whose quality isn't that good.)
They are often used when they're not needed and can make
otherwise simple problems difficult.

Doesn't that apply to just about everything in C++? Templates
are an obvious example (because they're the current mode), but
I've seen cases of overuse of just about every feature of C++.
On the other hand, most features are there for a reason, and not
using local statics can also make otherwise simple problems
difficult. It all depends on the problem.
 
R

Ross A. Finlayson

I cannot find anything in the current C++ standard that refers to anything
called a "thread". It falls outside of the scope; as such, as soon as
threads are introduced into the picture, the results are no longer defined
by the current standard. Instead, one must consult the documentation of the
particular C++ implementation to learn what the effects of threads are, in
that implementation.

 application_pgp-signature_part
< 1KViewDownload

How about, making a flag on the static initializer, and a write lock
that's only used once after the initialization so the initializer hits
the uninitialized flag, sets the write lock, and initializes and frees
the write lock and clears the uninitialized flag, but then a thread
waiting for the write lock because of the uninitialized flag might
want to initialize the function of the initializer otherwise failed,
so maybe there should be a timestamp with function calls and times
since the lock, so other functions can determine whether the lock is
frozen and break it, calling then the extra analyzers of the
verification of the static input record in an error-resistant network.

The idea here is to have first a flag that any caller can read. If
it's set, (or the function pointer can be pointed to after the static
initializer block after the first call), the the function is
initialized. If it's unset, then the caller calls the static
initializer of the function scope because the object isn't
initialized, instead of calling the initializer with the object, for
specialized initializers of functions' static members to not
initialize unused static members (lazy). So anyways, the function
takes the write lock that immediately follows the flag and sets it so
other function wait until the flag is cleared to proceed past that
point in the function. Then, it increments the following write
semaphore, which is only used if at all by other functions with
interest in how many calls to the function have tried to initialize
it. That is an extra step on the initializer. Then the static
variables are set up by the initializer, some of them are loaded at
class definitions, but in Java it is when the method is called.

About the scope blocks, and variable visibility, also there are often
static initializers throughout the function as the procedure demands
them besides in statement blocking, about the difference in the
program before and after the objects are statically initialized.

So, the specialized code path has that there are threading semantics
on the atomic static initialization of the object, because the
compiler automatically generates static initialization semantics via
the language definition and its semantics with regards to the linear
sequence of processing in statement blocks with jumps. Then, the user
might want there to be configurable levels of validation about when
other function families export semantics.

Using local static variables is great because if they're sufficient
then otherwise is waste, barring reclamation frameworks. C++ is great
in that the variables don't have to all be at the beginning of the
function, like traditional C, but then the order of initialization of
variables is pretty clearly specified except for example the design
choices about things like order of intialization in initializers and
so on, it's a feature of the language.

Then, with having more than just the one lock in the locks on the
static initializer and static initializers of nested local blocks,
with the flag, the lock, then the semaphore that is never decremented
unlike regular semaphore semantics but shouldn't hold a reference in
the semaphore table, it's more a simple count, there are various other
considerations of what information the calling function had before it
jumped to the static initializer block proper. The most recent time
written would expand the description of how long the process has been
in the write lock blocking other functions from calling the function,
where then if there were other functions that could initialize the
object and the normal initializer failed for some reason, there could
be a retry with in severely affected places, each variable to be
initialized having its own static initializer block semantics, with
waiting callers not being able to call the function proper but to
check on the status of the static initializer so see where it had set
write locks, in working towards locks that the caller might not want
to block upon, where a lock stops execution until the system calls
back another function released the lock, varying on whether the caller
really needs to call the function or can call parts of it that are
initialized already and not others.

It would of course be preferable to build the extensions into the
semantics of the language to avoid maintenance of static initializer
guards with whatever lock framework is in place, trying to make re-
entrant code safe about its static initializers

class static_initializer; // for this class in scope, mark the lock

static void static_initializer::end // here the writer knows it's done


void example_function(int i)
{
static_initializer; // following objects are protected to be
initialized one at a time
static large_table_of_constants t = new large_table_of_constants;
static_initializer::end; // no more with locked initialization
static const char const* label = "LABEL"; // don't care if this is
threadsafe, it's constant

return t.value(i);

}

Without a lock in the initializer, two functions could call the
example_function at around the same time, where the processor
allocates time just as the first is halfway through and the second
then starts, calling functions on the same object again, which is bad,
could lead to undefined behavior. It might not, the problem is then
there are two new tables and when the function exits the destructor
isn't called,where there is a question how to indicate a lights-out
call so then the function destroys its static variables, static
function destructors. As well, functions might want to generally
reset the variable besides worrying about the static variable, that is
preserved between function calls, in the run-time. That is where, I
wonder when static variables have their destructors called.

Regards,

Ross F.
 
J

James Kanze

Once again: the standard tells where to store the static
content and how often.

Only to a point. The standard gives the implementation the
right to do anything it pleases if the code contains undefined
behavior. Calling pthread_create or CreateThread results in
undefined behavior, according to the standard, so nothing the
compiler does in a multithreaded program will break conformance.

But that's really being overly pedantic. Compilers do support
threading. It just means that for the definition of what
happens in a multithreaded program, you have to look to the
compiler documentation, and not the standard. And you can
exterpolate to more or less define what you should be able to
reasonably expect---what would be a logical choice of options
for the compiler, or what you would expect from a QoI point of
view.
So by that it implicitly defines static content in functions
not very thread safe.

It doesn't imply anything. Obviously, if the function is called
from multiple threads, you have to treat the static variable as
you would any variable that is accessed from different threads,
but that's about it; there's no reason for there to be any
difference between local statics and other variables with static
lifetime.
 
R

Ramesh

Is it advisable to use a local static variable inside a function ? I
want to know whether there are any drawbacks of using local static
variable inside a function.

Kindly explain.

Thanks
V.Subramanian

There are some drawbacks of using static variables inside a function
like thread-safety issues, but there are some advantages too in some
cases. So I repeat Victor Bazarov, use it if you need it.
 

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,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top