[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

Use a static variable outside its function

pozz

4/2/2011 3:21:00 PM

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

char * foo(void) {
static char str[32];
sprintf (str, "foo");
return str;
}

int main(void) {
printf("%s", foo());
return 0;
}


Is it always possible to use a static variable (declared inside a
function) outside its declaration block, as in the example above?

Do you consider this a bad practice?
12 Answers

James Kuyper

4/2/2011 4:14:00 PM

0

On 04/02/2011 11:20 AM, pozz wrote:
> #include <stdio.h>
> #include <stdint.h>
> #include <stdlib.h>
>
> char * foo(void) {
> static char str[32];
> sprintf (str, "foo");
> return str;
> }
>
> int main(void) {
> printf("%s", foo());
> return 0;
> }
>
>
> Is it always possible to use a static variable (declared inside a
> function) outside its declaration block, as in the example above?

Sure. Why not? The key issue is whether or not the object pointed at by
the pointer still exists; since it is declared 'static', the answer is
"yes".

> Do you consider this a bad practice?

Not in itself.

However, static variables do tend to interfere with re-entrancy. For an
example of why this could be problematic, look at strtok(), and consider
what would happen if you wanted to parse two different strings in
parallel using strtok(). Or, equivalently, think about a case I actually
ran into: a calling function calls strtok() in a loop to parse one
string; in that same loop, it calls another function which also uses
strtok() to parse an entirely different string. Both functions were
written by different people, at very different times. One was part of a
library, the other was part of a program that used that library. I was
called in to investigate the bizarre consequences of linking the program
to that library.

My advice: use static variables only if you're certain that you will
never want to re-use the code in any context where you might want to
have two separate copies of the information stored in those variables.
--
James Kuyper

gw7rib

4/2/2011 4:50:00 PM

0

On Apr 2, 4:20 pm, pozz <pozzu...@gmail.com> wrote:
> #include <stdio.h>
> #include <stdint.h>
> #include <stdlib.h>
>
> char * foo(void) {
>    static char str[32];
>    sprintf (str, "foo");
>    return str;
>
> }
>
> int main(void) {
>    printf("%s", foo());
>    return 0;
>
> }
>
> Is it always possible to use a static variable (declared inside a
> function) outside its declaration block, as in the example above?

Yes, as James has said.

> Do you consider this a bad practice?

If the static variable was a number, then accessing it outside the
function would tend to indicate that it shouldn't be inside the
function in the first place.

Using a buffer, as you are doing, is one way of returing a string from
a function. Another way is for the calling function to provide a
buffer for your function to write in; a third way is for your function
to malloc a buffer, which the caller then frees. Each method has its
good and bad points. One snag with your method is that the output
string is limited in length; another is that calling the function
several times puts all the answers in the same place. For example (and
assuming a slightly different foo):

printf("%s %s", foo(1), foo(2));

will print the same string twice.

Hope this helps.
Paul.

James Dow Allen

4/2/2011 5:50:00 PM

0

James Kuyper <jameskuyper@verizon.net> might have writ, in news:in7i09
$pci$1@dont-email.me:

>> Is it always possible to use a static variable (declared inside a
>> function) outside its declaration block, as in the example above?
>
> My advice: use static variables only if you're certain that you will
> never want to re-use the code in any context where you might want to
> have two separate copies of the information stored in those variables.

There's a simple solution to the reuse problem which is *sometimes*
adequate; I've used it *lots* of times. I'm *certain* my post here will
draw angry responses telling me how stupid my suggestion is! My only
defense is that for the simple applications I write, seeking perfection
is a time waster, when a kluge is "good enough."

char *romanize(int x) /* Render x in Roman numerals */
{
/* Be sure these "magic" numbers are big enough!! :-( */
static char rnbuff[20][40];
static int rnbindex = 0;
char *outbuff = rnbuff[rnbindex = (rnbindex + 1) % 20];

whatever ...; /* place result in *outbuff */
return outbuff;
}

main()
{
....
printf("Each of %s wives has %s bags; each with %s cats\n",
romanize(numwife), romanize(numbag), romanize(numcat));
}

I'm donning my asbestos suit.

James Dow Allen

Eric Sosman

4/2/2011 6:58:00 PM

0

On 4/2/2011 11:20 AM, pozz wrote:
> #include <stdio.h>
> #include <stdint.h>
> #include <stdlib.h>
>
> char * foo(void) {
> static char str[32];
> sprintf (str, "foo");
> return str;
> }
>
> int main(void) {
> printf("%s", foo());
> return 0;
> }
>
>
> Is it always possible to use a static variable (declared inside a
> function) outside its declaration block, as in the example above?

Yes. Well, technically you're not using the variable itself;
the variable name `str' is known only inside foo() and not outside
it in main(). But foo() returns a pointer to the memory-resident
array object designated by `str', and that object exists throughout
the entire execution of the program. In particular, it exists when
main() passes the pointer to printf() and when printf() uses the
pointer to get at the array content.

> Do you consider this a bad practice?

Yes. No. Almost everything is bad practice if there's no good
reason for it; given good reasons, few practices are wholly bad.

--
Eric Sosman
esosman@ieee-dot-org.invalid

Ike Naar

4/3/2011 12:40:00 AM

0

On 2011-04-02, James Dow Allen <gmail@jamesdowallen.nospam> wrote:
> James Kuyper <jameskuyper@verizon.net> might have writ, in news:in7i09
> $pci$1@dont-email.me:
>
>>> Is it always possible to use a static variable (declared inside a
>>> function) outside its declaration block, as in the example above?
>>
>> My advice: use static variables only if you're certain that you will
>> never want to re-use the code in any context where you might want to
>> have two separate copies of the information stored in those variables.
>
> There's a simple solution to the reuse problem which is *sometimes*
> adequate; I've used it *lots* of times. I'm *certain* my post here will
> draw angry responses telling me how stupid my suggestion is! My only
> defense is that for the simple applications I write, seeking perfection
> is a time waster, when a kluge is "good enough."
>
> char *romanize(int x) /* Render x in Roman numerals */
> {
> /* Be sure these "magic" numbers are big enough!! :-( */
> static char rnbuff[20][40];
> static int rnbindex = 0;
> char *outbuff = rnbuff[rnbindex = (rnbindex + 1) % 20];
>
> whatever ...; /* place result in *outbuff */
> return outbuff;
> }
>
> main()
> {
> ....
> printf("Each of %s wives has %s bags; each with %s cats\n",
> romanize(numwife), romanize(numbag), romanize(numcat));
> }
>
> I'm donning my asbestos suit.
>
> James Dow Allen
>


--
ike@sdf.lonestar.org
SDF Public Access UNIX System - http://sdf.lo...

Ike Naar

4/3/2011 12:46:00 AM

0

On 2011-04-03, Ike Naar <ike@iceland.freeshell.org> wrote:
> [a quote from James Dow Allen, and nothing more]

Sorry, posted by accident; please ignore.

Ralph Spitzner

4/3/2011 1:28:00 AM

0

pozz wrote:
[...]
> char * foo(void) {
> static char str[32];
> sprintf (str, "foo");
> return str;
> }

Will you ever expect that anything could happen
to 'str' ?
(except assigning 'foo' to it)

If so, what tells you there will be no more than 32
chars ?

If not, use a 'constant' string, or #define
else try malloc/free :-P

-rasp


J. J. Farrell

4/3/2011 1:39:00 AM

0

Ike Naar wrote:
> On 2011-04-03, Ike Naar <ike@iceland.freeshell.org> wrote:
>> [a quote from James Dow Allen, and nothing more]
>
> Sorry, posted by accident; please ignore.

I thought his suggestion had left you speechless ...

Joel C. Salomon

4/4/2011 4:54:00 PM

0

"James Dow Allen" <gmail@jamesdowallen.nospam> wrote:
>>> Is it always possible to use a static variable (declared inside a
>>> function) outside its declaration block, as in the example above?
>
> There's a simple solution to the reuse problem which is *sometimes*
> adequate; I've used it *lots* of times. I'm *certain* my post here will
> draw angry responses telling me how stupid my suggestion is! My only
> defense is that for the simple applications I write, seeking perfection
> is a time waster, when a kluge is "good enough."
<snip>
> I'm donning my asbestos suit.

Call it a lazilly-generated table; that should be sufficiently buzzword-compliant for safetly. ;)

--Joel

Jorgen Grahn

4/12/2011 7:45:00 PM

0

On Sat, 2011-04-02, James Dow Allen wrote:
> James Kuyper <jameskuyper@verizon.net> might have writ, in news:in7i09
> $pci$1@dont-email.me:
>
>>> Is it always possible to use a static variable (declared inside a
>>> function) outside its declaration block, as in the example above?
>>
>> My advice: use static variables only if you're certain that you will
>> never want to re-use the code in any context where you might want to
>> have two separate copies of the information stored in those variables.
>
> There's a simple solution to the reuse problem which is *sometimes*
> adequate; I've used it *lots* of times. I'm *certain* my post here will
> draw angry responses telling me how stupid my suggestion is! My only
> defense is that for the simple applications I write, seeking perfection
> is a time waster, when a kluge is "good enough."
>
> char *romanize(int x) /* Render x in Roman numerals */
> {
> /* Be sure these "magic" numbers are big enough!! :-( */
> static char rnbuff[20][40];
> static int rnbindex = 0;
> char *outbuff = rnbuff[rnbindex = (rnbindex + 1) % 20];
>
> whatever ...; /* place result in *outbuff */
> return outbuff;
> }
>
> main()
> {
> ....
> printf("Each of %s wives has %s bags; each with %s cats\n",
> romanize(numwife), romanize(numbag), romanize(numcat));
> }
>
> I'm donning my asbestos suit.

No asbestos needed, I think. I've seen this strategy in real code ...
I *much* prefer it to a single static buffer and subtly corrupted
output in important log files!

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .