473,320 Members | 1,990 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

question on static variable in a function

In the following link,
http://www.c-faq.com/malloc/retaggr.html

The following ANSWER is given to a question(comp.lang.c FAQ list ·
Question 7.5a) :

Whenever a function returns a pointer, make sure that the pointed-to
memory is properly allocated. For example, make sure you have not done
something like

#include <stdio.h>

char *itoa(int n)
{
char retbuf[20]; /* WRONG */
sprintf(retbuf, "%d", n);
return retbuf; /* WRONG */
}

When a function returns, its automatic, local variables are discarded,
so the returned pointer in this case is invalid (it points to an array
that no longer exists).

One fix would be to declare the return buffer as

static char retbuf[20];

This fix is imperfect, since a function using static data is not
reentrant.

My question is what "reentrant" means here? Why is static data inside
function discouraged ?

Mar 6 '07 #1
14 3418
In article <11********************@c51g2000cwc.googlegroups.c om>,
su**************@yahoo.com, India <su**************@yahoo.comwrote:
....
>When a function returns, its automatic, local variables are discarded,
so the returned pointer in this case is invalid (it points to an array
that no longer exists).

One fix would be to declare the return buffer as

static char retbuf[20];

This fix is imperfect, since a function using static data is not
reentrant.

My question is what "reentrant" means here? Why is static data inside
function discouraged ?
There are at least 3 things that can go wrong using this approach:
1) The primary import of the phrase "not reentrant" is that it
can't be used in a multi-threaded application. I.e., in a
multi-thread, there could be more than one active
invocation of the function.
2) Functions with static data cannot be called recursively.
3) The following code, although not involving either recursion
or threading, doesn't work as expected:

char *a,*b;
a = afunc(someparams);
b = afunc(someparams);
/* Do something with a & b */

It is actually #3 above that's the most annoying (IMHO).

Mar 6 '07 #2
"su**************@yahoo.com, India" <su**************@yahoo.com>
writes:
static char retbuf[20];

This fix is imperfect, since a function using static data is not
reentrant.

My question is what "reentrant" means here? Why is static data inside
function discouraged ?
If you call the function twice, then the answer you get on the
second call will replace the answer you get on the first call.
Unless you make a copy of the value returned the first time, or
you don't need to refer to it after the second call, this can be
very surprising.

This is not, strictly speaking, what "reentrant" is generally
taken to mean, but it is the problem that you will encounter in
this situation.
--
"C has its problems, but a language designed from scratch would have some too,
and we know C's problems."
--Bjarne Stroustrup
Mar 6 '07 #3
I understand your points 1) and 3). But I have used static integer
counter variable in a recursive method which works.

I cannot understand the reason as to why recursive function
cannot contain static data.

Mar 6 '07 #4
On Mar 6, 6:17 am, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.comwrote:
>
My question is what "reentrant" means here? Why is static data inside
function discouraged ?
Specifically, "reentrant" means that an application can re-enter the
function while already executing the function, whether by recursion or
in the execution of a different thread. This makes sense, right?
Since static data persists across multiple executions of a function,
if one line of execution is using that data and another modifies it,
you are almost certainly going to encounter problems.

Nor can variables declared static be relied upon to act as thread
control flags (unless they are part of some well-crafted thread
library that will very likely use implementation specific resources to
guarantee thread safety). The following, for example, cannot be relied
upon to work correctly:

void do_some_multithreaded_work(char* param) {
static int active = 0;

try_again:
if (active) {
goto try_again;
} else {
active = 1;
/* do something to param */
active = 0;
}
}

Why? Because two threads could be so close together, that both would
pass the "if (active)" test before either set active to 1. If you were
trying to protect this because both threads might be working on the
same character string pointed to by param, then you could have both
threads acting on param at the same time, which is probably not what
you want. Ok, not a *great* example, but you get the point, I hope.

Recursion is a little different. A static int might be useful for
counting your recursion depth, for example:

void recursive_func(void) {
static int depth = 0;
depth++;
if (depth 10) return;
recursive_func();
}

Ok, possibly an even worse example, if you think about it a little,
but you see how the depth counter would work?

What you wouldn't want in a recursive function would be static data
that participates in the work of the function that calls itself (or
can be called lower in the call chain from within this function).
Sure, there are exceptions, but in general, you're asking for trouble.

Data that is static within a function is a lot like an old fashioned
global variable: it has many of the same drawbacks, and thus is
generally discouraged. It doesn't have global scope, it can't be used
willy nilly from everywhere, but as it spans both time and multiple
lines of execution, it's a hazard.

-Bluejack

Mar 6 '07 #5
On Mar 6, 9:17 am, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.comwrote:
In the following link,http://www.c-faq.com/malloc/retaggr.html

The following ANSWER is given to a question(comp.lang.c FAQ list ·
Question 7.5a) :

Whenever a function returns a pointer, make sure that the pointed-to
memory is properly allocated.
[snip]
When a function returns, its automatic, local variables are discarded,
so the returned pointer in this case is invalid (it points to an array
that no longer exists).

One fix would be to declare the return buffer as

static char retbuf[20];

This fix is imperfect, since a function using static data is not
reentrant.

My question is what "reentrant" means here? Why is static data inside
function discouraged ?
Consider the following code fragments...

#include <stdio.h>

char *foo(int bar)
{
char baz[256];

sprintf(baz,"%d",bar);
return baz;
}

void somefunc(void)
{
printf("%s, %s\n",foo(10),foo(-999));
}

What will printf() in somefunc() print?
Why?

--
Lew

Mar 6 '07 #6
Kenny McCormack wrote:
2) Functions with static data cannot be called recursively.
I don't think that's what you mean to say, since they
can, and further the effect of having a static can
be useful. (Apart from scoping issues, it's the same
as having the static outside the function, of course.)

--
Mobile Hedgehog
A rock is not a fact. A rock is a rock.

Mar 6 '07 #7
A minor correction

On Mar 6, 10:56 am, "Lew Pitcher" <lpitc...@sympatico.cawrote:
On Mar 6, 9:17 am, "subramanian10...@yahoo.com, India"

<subramanian10...@yahoo.comwrote:
In the following link,http://www.c-faq.com/malloc/retaggr.html
The following ANSWER is given to a question(comp.lang.c FAQ list ·
Question 7.5a) :
Whenever a function returns a pointer, make sure that the pointed-to
memory is properly allocated.
[snip]
When a function returns, its automatic, local variables are discarded,
so the returned pointer in this case is invalid (it points to an array
that no longer exists).
One fix would be to declare the return buffer as
static char retbuf[20];
This fix is imperfect, since a function using static data is not
reentrant.
My question is what "reentrant" means here? Why is static data inside
function discouraged ?

Consider the following code fragments...

#include <stdio.h>

char *foo(int bar)
{
char baz[256];
Make that

static char baz[256];

Sorry :-S
>
sprintf(baz,"%d",bar);
return baz;
}

void somefunc(void)
{
printf("%s, %s\n",foo(10),foo(-999));
}

What will printf() in somefunc() print?
Why?

--
Lew

Mar 6 '07 #8
On 6 Mar 2007 06:17:46 -0800, in comp.lang.c ,
"su**************@yahoo.com, India" <su**************@yahoo.com>
wrote:

(of static local variables and their unsuitability )
>My question is what "reentrant" means here? Why is static data inside
function discouraged ?
If you call the function in several different threads, or call it
recursively, or call it twice in a function argument list, you may get
peculiar answers, or even possibly a crash.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Mar 6 '07 #9
In article <Qd*******************@fe1.news.blueyonder.co.uk >,
Chris Dollin <eh@electrichedgehog.netwrote:
>Kenny McCormack wrote:
>2) Functions with static data cannot be called recursively.

I don't think that's what you mean to say, since they
can, and further the effect of having a static can
be useful. (Apart from scoping issues, it's the same
as having the static outside the function, of course.)
Others have addressed this. Short answer: Yes, I did mean it, but I
didn't go through all the necessary hoops to make it nitpick-proof.

Among others, Mark McI says:

If you call the function in several different threads, or call it
*recursively* (emphasis mine, Ed.) , or call it twice in a function
argument list, you may get peculiar answers, or even possibly a crash.

Mar 6 '07 #10
"su**************@yahoo.com, India" wrote:
>
I understand your points 1) and 3). But I have used static integer
counter variable in a recursive method which works.

I cannot understand the reason as to why recursive function
cannot contain static data.
It can if you only call it once from outside, or if you don't use
the variable. I can think of other limited scenarios.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
Mar 6 '07 #11
In article <vu********************************@4ax.com>,
Mark McIntyre <ma**********@spamcop.netwrote:
>If you call the function in several different threads, or call it
recursively, or call it twice in a function argument list, you may get
peculiar answers, or even possibly a crash.
Isn't it guaranteed that function calls in an argument list are called
without overlap?

-- Richard

--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Mar 6 '07 #12
On 6 Mar 2007 23:30:12 GMT, in comp.lang.c , ri*****@cogsci.ed.ac.uk
(Richard Tobin) wrote:
>In article <vu********************************@4ax.com>,
Mark McIntyre <ma**********@spamcop.netwrote:
>>If you call the function in several different threads, or call it
recursively, or call it twice in a function argument list, you may get
peculiar answers, or even possibly a crash.

Isn't it guaranteed that function calls in an argument list are called
without overlap?
AFAIR the order in which they're evaluated is unspecified, so I
believe that

f1(f2(3), f2(2)) ;

might result in either f2(2) or f2(3) being evaluated first, or even
possibly both at once. I could probably construct a pathological
example of where this would matter but its not hard ot think of one.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Mar 6 '07 #13
In article <ma********************************@4ax.com>,
Mark McIntyre <ma**********@spamcop.netwrote:
>>Isn't it guaranteed that function calls in an argument list are called
without overlap?
>AFAIR the order in which they're evaluated is unspecified, so I
believe that

f1(f2(3), f2(2)) ;

might result in either f2(2) or f2(3) being evaluated first,
Yes.
>or even possibly both at once.
Surely no, because there is a sequence point before each of the
functions is called.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Mar 7 '07 #14
In article <ma********************************@4ax.com>,
Mark McIntyre <ma**********@spamcop.netwrote:
>On 6 Mar 2007 23:30:12 GMT, in comp.lang.c , ri*****@cogsci.ed.ac.uk
(Richard Tobin) wrote:
>>In article <vu********************************@4ax.com>,
Mark McIntyre <ma**********@spamcop.netwrote:
>>>If you call the function in several different threads, or call it
recursively, or call it twice in a function argument list, you may get
peculiar answers, or even possibly a crash.

Isn't it guaranteed that function calls in an argument list are called
without overlap?

AFAIR the order in which they're evaluated is unspecified, so I
believe that

f1(f2(3), f2(2)) ;

might result in either f2(2) or f2(3) being evaluated first, or even
possibly both at once. I could probably construct a pathological
example of where this would matter but its not hard ot think of one.
I believe that there are sequence points around the actual function call,
which would force them to not be interleaved modulo the as-if rule.

I seem to recall somebody pointing out to me that that didn't apply to
evaluation of the arguments, though, so
f1(f2(f2_args),f3(f3_args));
could happen as:
--------
evaluate f2 arguments }
evaluate f3 arguments } May be interleaved
(Sequence point)
call f2 >
(Sequence point) order not specified
call f3 >
(sequence point)
call f1
--------

So, f'rexample, something like:
--------
#include <stdio.h>
int foo(void)
{
static int i;
return i++;
}
int main(void)
{
printf("%d %d\n",foo(),foo());
return 0;
}
--------
doesn't invoke undefined behavior (it must print either "1 2\n" or
"2 1\n"), but this one:
--------
#include <stdio.h>
int foo(int i) { return i; }
int main(void)
{
int i=0;
printf("%d %d\n",foo(i++),foo(i++));
return 0;
}
--------
is allowed to cause a rhinodaemon infestation.
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
your a morron.
Beautiful. Classic sig block material.
--Richard Heathfield roasts a troll in comp.lang.c
Mar 7 '07 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: mlimber | last post by:
This is a repost (with slight modifications) from comp.lang.c++.moderated in an effort to get some response. I am using Loki's Factory as presented in _Modern C++ Design_ for message passing in...
3
by: Datta Patil | last post by:
Hi , #include<stdio.h> func(static int k) /* point2 : why this is not giving error */ { int i = 10 ; // static int j = &i ; /* point 1: this will give compile time error */ return k; } /*...
3
by: juli jul | last post by:
Hello! If I want to pass some class variable from one class to another : how can I do it with the static function? I tried but I can't see the class variables in the static function I made-are...
11
by: dhnriverside | last post by:
Hi peeps Ok, so I thought I'd have a go at making a console app in VS2k5... I haven't written any windows apps for years, let alone dos apps (been web programming) and I've hit a dumb error... ...
8
by: Steven Scaife | last post by:
Hello I am creating a reporting system using SQL Server 2000 and ASP, I have created 4 pages that display the results i want, however the reports take an average of 20 mins to run and i have...
10
by: Franky | last post by:
I think I misread a post and understood that if I do: System.Windows.Forms.Cursor.Current = Cursors.WaitCursor there is no need to reset the cursor to Default. So I made all the reset...
55
by: Zytan | last post by:
I see that static is more restricted in C# than in C++. It appears usable only on classes and methods, and data members, but cannot be created within a method itself. Surely this is possible in...
10
by: Pramod | last post by:
Hello to all of you, I want to know that what's the use to create static object. Thanks You Pramod Sahgal
12
by: Bryan Parkoff | last post by:
I write my large project in C++ source code. My C++ source code contains approximate four thousand small functions. Most of them are inline. I define variables and functions in the global scope....
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.