safe to return a pointer to static storage?

J

Jim Showalter

I always thought that it is safe for a function to return a pointer to
static storage. And the following code does compile quietly with:

gcc -pedantic -Wall -o foo foo.c

#include <stdio.h>

static char *foo (int y)
{
static char s[10];
sprintf(s, "%d", y);
return s;
}

int main(void)
{
int y = 999;
printf("y = %s\n", foo(y));
return 0;
}

But 'splint' (the 'lint' program supplied with RedHat Linux)
gives the following complaints:

Splint 3.0.1.6 --- 27 May 2002

foo.c: (in function foo)
foo.c:7:12: Unqualified static storage s returned as implicitly only: s
Static storage is transferred in an inconsistent way. (Use -statictrans to
inhibit warning)
foo.c: (in function main)
foo.c:13:21: New fresh storage (type char *) passed as implicitly temp (not
released): foo(y)
Amemory leak has been detected. Storage allocated locally is not released
before the last reference to it is lost. (Use -mustfreefresh to inhibit
warning)

Finished checking --- 2 code warnings

Is this _really_ a memory leak? Or is splint overly paranoid?

droid
 
E

Emmanuel Delahaye

Jeff said:
what are the strange side effects ?

int inc (void)
{
static S_i = 0;

S_i++;

return S_i;
}

include <stdio.h>

int main (void)
{
/* the output is unpredictable */
printf ("%d %d\n", inc(), inc());

return 0;
}

even worst with static strings. See strftime() for example.

Not to mention unwanted recursive calls or multithreading.
 
J

Jeff

Jim Showalter said:
I always thought that it is safe for a function to return a pointer to
static storage. And the following code does compile quietly with:

gcc -pedantic -Wall -o foo foo.c

#include <stdio.h>

static char *foo (int y)
{
static char s[10];
sprintf(s, "%d", y);
return s;
}

int main(void)
{
int y = 999;
printf("y = %s\n", foo(y));
return 0;
}

But 'splint' (the 'lint' program supplied with RedHat Linux)
gives the following complaints:

Splint 3.0.1.6 --- 27 May 2002

foo.c: (in function foo)
foo.c:7:12: Unqualified static storage s returned as implicitly only: s
Static storage is transferred in an inconsistent way. (Use -statictrans to
inhibit warning)
foo.c: (in function main)
foo.c:13:21: New fresh storage (type char *) passed as implicitly temp (not
released): foo(y)
Amemory leak has been detected. Storage allocated locally is not released
before the last reference to it is lost. (Use -mustfreefresh to inhibit
warning)

Finished checking --- 2 code warnings

Is this _really_ a memory leak? Or is splint overly paranoid?

droid

I found that the ANSI time function localtime( ), gmtime( ) and mktime( ) also return a pointer to
a static storage structure "tm". I think you are right, it is safe to return a pointer to static
storage.
 
D

Dan Pop

In said:
I always thought that it is safe for a function to return a pointer to
static storage.

It is safe, but it can lead to program bugs, if you're not extremely
careful. Consider the following example:

printf("y = %s, z = %s\n", foo(y), foo(z));

The bug is far from obvious to the non-experienced C programmer.
And the following code does compile quietly with:

gcc -pedantic -Wall -o foo foo.c

As it should. You may also want to add -ansi and -O (-Wall is not
complete without -O), especially for code you intend to post to
this newsgroup :)
#include <stdio.h>

static char *foo (int y)
{
static char s[10];
sprintf(s, "%d", y);
return s;
}

int main(void)
{
int y = 999;
printf("y = %s\n", foo(y));
return 0;
}

But 'splint' (the 'lint' program supplied with RedHat Linux)
gives the following complaints:

Splint 3.0.1.6 --- 27 May 2002

foo.c: (in function foo)
foo.c:7:12: Unqualified static storage s returned as implicitly only: s
Static storage is transferred in an inconsistent way. (Use -statictrans to
inhibit warning)

Nonsensical diagnostic.
foo.c: (in function main)
foo.c:13:21: New fresh storage (type char *) passed as implicitly temp (not
released): foo(y)

Idiotic diagnostic.
Amemory leak has been detected. Storage allocated locally is not released
before the last reference to it is lost. (Use -mustfreefresh to inhibit
warning)
Bullshit.

Finished checking --- 2 code warnings

Is this _really_ a memory leak?

Obviously NOT. Whoever implemented these checks should have his own head
checked.
Or is splint overly paranoid?

Brain dead.

If you want to keep using splint (or any other form of lint), you'll have
to learn how to disable all the checks that only produce garbage output.

In my opinion, a properly invoked gcc removes the need for lint checks.

Dan
 
J

Jeff

I found that the ANSI time function localtime( ), gmtime( ) and mktime( ) also return a pointer
to
a static storage structure "tm".

I have made a mistake, the function mktime( ) do not return structure tm, it returns time_t.
 
J

Jim Showalter

[snip]
Or is splint overly paranoid?

Brain dead.

If you want to keep using splint (or any other form of lint), you'll have
to learn how to disable all the checks that only produce garbage output.

In my opinion, a properly invoked gcc removes the need for lint checks.

Well, as I said, I _just_ started using splint and I'm not impressed. You
make a good point. I think I'll just stick to using gcc (with the switches
you and others suggested) and save myself the agro. :)


Thanks again Dan!

Jim Showalter
 
G

Grant D. Watson

Well, as I said, I _just_ started using splint and I'm not impressed. You
make a good point. I think I'll just stick to using gcc (with the switches
you and others suggested) and save myself the agro. :)

Well, I just started playing with it myself. If you add the -weak switch, it
turns off some of its more pedantic stuff. (It appears that -weak enables the
stort of thing that can be checked for without you marking up your code, while
leaving it out makes Splint do all the checks that assume you've marked up your
code.)

E.g.,
splint -weak *.c

I also like the various bool switches: -booltype, -boolfalse and -booltrue,
that make it understand that my BOOL typedef type really means boolean.

Grant D. Watson
(e-mail address removed) (Use this one!)
 

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

No members online now.

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,692
Latest member
JenniferTi

Latest Threads

Top