473,473 Members | 1,752 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Pointer to static storage causing warning by code-checker

Hello there,

I'm having trouble understanding a warning produced by 'splint', a
code-checker. The warning produced is:

keywords.c: (in function keyw_get_string)
keywords.c:60:31: Released storage Keywords[].Keyword reachable from global
A global variable does not satisfy its annotations when control
is transferred. (Use -globstate to inhibit warning)
keywords.c:60:11: Storage Keywords[].Keyword released

The line number isn't correct anymore since I snipped some 'irrelevant'
code. Here's the code that causes the warning:

/*
* keywords module for sta65xx, written by Bas Wassink
* started: 2005-09-13
* updated: 2005-09-16
*/

#include <string.h>
#include <stdio.h>

#include "globals.h" /* application wide used constants */
#include "keywords.h" /* prototypes and constants used */

struct keystruct { /* struct used by Keywords table */
char *Keyword;
int Id;
char *Description;
};

/* keywords table */
static struct keystruct Keywords[] = {
{ "byte", KEYW_BYTE, "data as bytes" },
{ "word", KEYW_WORD, "data as words" },
{ "text", KEYW_TEXT, "data as text" }
};

/* return keyword string */
char *keyw_get_string ( int k )
{
int i;

/* check identifier bounds */
if ( ( k >= KEYWORDS_AMOUNT ) || ( k < 0 ) )
return NULL;

/* look up Id in table */
for ( i = 0; i < KEYWORDS_AMOUNT; i++ )
if ( Keywords[i].Id == k )
return Keywords[i].Keyword; /* <= This causes the warning */

/* Id not found, return NULL as error code (shouldn't happen) */
return NULL;
}
I know I'm returning a pointer to memory accessible only by this module,
so that's probably what causes the warning, but I still don't quite
understand the warning.

If anyone could explain what I might be doing wrong, I'd be much obliged.

Bas Wassink.
Nov 15 '05 #1
3 2694
Bas Wassink wrote:

Hello there,

I'm having trouble understanding a warning produced by 'splint', a
code-checker. The warning produced is:

keywords.c: (in function keyw_get_string)
keywords.c:60:31: Released storage Keywords[].Keyword reachable from global
A global variable does not satisfy its annotations when control
is transferred. (Use -globstate to inhibit warning)
keywords.c:60:11: Storage Keywords[].Keyword released

The line number isn't correct anymore since I snipped some 'irrelevant'
code.
Does the code, as posted, still give the warning?

Here's the code that causes the warning: [...] /* keywords table */
static struct keystruct Keywords[] = {
{ "byte", KEYW_BYTE, "data as bytes" },
{ "word", KEYW_WORD, "data as words" },
{ "text", KEYW_TEXT, "data as text" }
};
Keywords[] is global, and Keywords[].Keyword isn't release anywhere
ythat I can see, so I don't see why you would get the warning on:
/* return keyword string */
char *keyw_get_string ( int k )
{ [...] return Keywords[i].Keyword; /* <= This causes the warning */ [...] }

I know I'm returning a pointer to memory accessible only by this module,
so that's probably what causes the warning, but I still don't quite
understand the warning.

If anyone could explain what I might be doing wrong, I'd be much obliged.


The memory is accessible to other modules, as long as you pass the
address somehow to that other module, as you do in the above return
statement. The Keywords[] array is not known outside the scope of
this module, due to the "static" modifier, but that doesn't mean you
can't pass its address around.

Please verify that the code, as posted, still gives the warning. If
not, then perhaps part of that "irrelevant" code you snipped wasn't
so "irrelevant" after all.

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Nov 15 '05 #2
On Fri, 16 Sep 2005 11:09:56 -0400, Kenneth Brody wrote:
Bas Wassink wrote:

Hello there,

I'm having trouble understanding a warning produced by 'splint', a
code-checker. The warning produced is:

keywords.c: (in function keyw_get_string)
keywords.c:60:31: Released storage Keywords[].Keyword reachable from global
A global variable does not satisfy its annotations when control
is transferred. (Use -globstate to inhibit warning)
keywords.c:60:11: Storage Keywords[].Keyword released

The line number isn't correct anymore since I snipped some 'irrelevant'
code.


Does the code, as posted, still give the warning?

Here's the code that causes the warning:

[...]
/* keywords table */
static struct keystruct Keywords[] = {
{ "byte", KEYW_BYTE, "data as bytes" },
{ "word", KEYW_WORD, "data as words" },
{ "text", KEYW_TEXT, "data as text" }
};


Keywords[] is global, and Keywords[].Keyword isn't release anywhere
ythat I can see, so I don't see why you would get the warning on:
/* return keyword string */
char *keyw_get_string ( int k )
{

[...]
return Keywords[i].Keyword; /* <= This causes the warning */

[...]
}

I know I'm returning a pointer to memory accessible only by this module,
so that's probably what causes the warning, but I still don't quite
understand the warning.

If anyone could explain what I might be doing wrong, I'd be much obliged.


The memory is accessible to other modules, as long as you pass the
address somehow to that other module, as you do in the above return
statement. The Keywords[] array is not known outside the scope of
this module, due to the "static" modifier, but that doesn't mean you
can't pass its address around.

Please verify that the code, as posted, still gives the warning. If
not, then perhaps part of that "irrelevant" code you snipped wasn't
so "irrelevant" after all.


Fair enough, here's the entire piece of code:

keywords.h:

/*
* Header file for keywords.c
*/

#define KEYWORDS_MAXWIDTH 10
#define KEYWORDS_AMOUNT 8

#define KEYW_BYTE 1
#define KEYW_WORD 2
#define KEYW_TEXT 3
#define KEYW_ASC 4
#define KEYW_PET 5
#define KEYW_ADDR 6
#define KEYW_MACRO 7
#define KEYW_SCOPE 8

int keyw_get_id ( char *s );
char *keyw_get_string ( int k );
void keyw_list ( void );
keywords.c:

/*
* keywords module for sta65xx, written by Bas Wassink
* started: 2005-09-13
* updated: 2005-09-16
*/

#include <string.h>
#include <stdio.h>

#include "globals.h" /* application wide used constants */
#include "keywords.h" /* prototypes and constants used */
#include "libstr65.h" /* used for safe strlen */

struct keystruct { /* struct used by Keywords table */
char *Keyword;
int Id;
char *Description;
};
/* keywords table */
static struct keystruct Keywords[] = {
{ "byte", KEYW_BYTE, "data as bytes" },
{ "word", KEYW_WORD, "data as words" },
{ "text", KEYW_TEXT, "data as text" },
{ "asc", KEYW_ASC, "data as ASCII text" },
{ "pet", KEYW_PET, "data as PETSCII text" },
{ "addr", KEYW_ADDR, "set program counter" },
{ "macro", KEYW_MACRO, "declare macro" },
{ "scope", KEYW_SCOPE, "set scope" }
};

/* return keyword identifier */
int keyw_get_id ( char *s )
{
int k;

for ( k = 0; k < KEYWORDS_AMOUNT; k++ ) {
if ( strcmp ( Keywords[k].Keyword, s ) == 0 )
return Keywords[k].Id;
}
return -1;
}

/* return keyword string */
char *keyw_get_string ( int k )
{
int i;

/* check identifier bounds */
if ( ( k >= KEYWORDS_AMOUNT ) || ( k < 0 ) )
return NULL;

/* look up Id in table */
for ( i = 0; i < KEYWORDS_AMOUNT; i++ )
if ( Keywords[i].Id == k )
return Keywords[i].Keyword;

/* not found, return NULL as error code (shouldn't happen) */
return NULL;
}

/* dump keyword list and descriptions to stdout */
void keyw_list ( void )
{
int k;
long n;

for ( k = 0; k < KEYWORDS_AMOUNT; k++ ) {
fprintf ( stdout, ".%s", Keywords[k].Keyword );
for ( n = str65_len(Keywords[k].Keyword); n < KEYWORDS_MAXWIDTH; n++ )
fprintf ( stdout, " " );
fprintf ( stdout, "%s\n", Keywords[k].Description );
}
}
And here's the output from splint:

compyx@athlonbox ~/projects/assembler $ splint keywords.c
Splint 3.1.1 --- 31 Aug 2005

keywords.c: (in function keyw_get_string)
keywords.c:52:10: Null storage returned as non-null: NULL
Function returns a possibly null pointer, but is not declared using
/*@null@*/ annotation of result. If function may return NULL, add /*@null@*/
annotation to the return value declaration. (Use -nullret to inhibit warning)
keywords.c:57:31: Released storage Keywords[].Keyword reachable from global
A global variable does not satisfy its annotations when control is
transferred. (Use -globstate to inhibit warning)
keywords.c:57:11: Storage Keywords[].Keyword released
keywords.c:60:9: Null storage returned as non-null: NULL

Finished checking --- 3 code warnings

Nov 15 '05 #3
Bas Wassink wrote on 16/09/05 :
I'm having trouble understanding a warning produced by 'splint', a
code-checker. The warning produced is:

keywords.c: (in function keyw_get_string)
keywords.c:60:31: Released storage Keywords[].Keyword reachable from global
A global variable does not satisfy its annotations when control
is transferred. (Use -globstate to inhibit warning)
keywords.c:60:11: Storage Keywords[].Keyword released
Sounds weird...
The line number isn't correct anymore since I snipped some 'irrelevant'
code. Here's the code that causes the warning:
<...>
I know I'm returning a pointer to memory accessible only by this module,
so that's probably what causes the warning, but I still don't quite
understand the warning.

If anyone could explain what I might be doing wrong, I'd be much obliged.


I have detected some other minor nitpicks that your code checker have
ignored... (-ed-)

/*
* keywords module for sta65xx, written by Bas Wassink
* started: 2005-09-13
* updated: 2005-09-16
*/

#include <string.h>
#include <stdio.h>

/* -ed- my guess (found in missing headers) */
enum
{
KEYW_BYTE,
KEYW_WORD,
KEYW_TEXT,
KEYW_dummy
};

/* -ed- 'const' added due to my paranoid settings... */
char const *keyw_get_string (int k);
#define KEYWORDS_AMOUNT ((int)(sizeof Keywords/sizeof *Keywords))

struct keystruct
{ /* struct used by Keywords table */
/* -ed- 'const' added due to my paranoid settings... */
char const *Keyword;
int Id;
/* -ed- 'const' added due to my paranoid settings... */
char const *Description;
};

/* keywords table */
static struct keystruct Keywords[] =
{
{"byte", KEYW_BYTE, "data as bytes"},
{"word", KEYW_WORD, "data as words"},
{"text", KEYW_TEXT, "data as text"}
};

/* return keyword string */
char const *keyw_get_string (int k)
/* -ed- was 'int' due to my paranoid settings... */
{
size_t i; /* -ed- was 'int' due to my paranoid
settings... */

/* check identifier bounds */
if ((k >= KEYWORDS_AMOUNT) || (k < 0))
return NULL;

/* look up Id in table */
for (i = 0; i < KEYWORDS_AMOUNT; i++)
if (Keywords[i].Id == k)
return Keywords[i].Keyword; /* <= This causes the warning */

/* Id not found, return NULL as error code (shouldn't happen) */
return NULL;
}

but I don't find anything wrong with the returning of the address of
the 1st element of a static array.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"It's specified. But anyone who writes code like that should be
transmogrified into earthworms and fed to ducks." -- Chris Dollin CLC
Nov 15 '05 #4

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

Similar topics

10
by: Dave | last post by:
const static int ARRAY_SIZE = 4; Comeau online gives this warning: "ComeauTest.c", line 10: warning: storage class is not first const static int ARRAY_SIZE = 4; Why is static const...
5
by: wallacej | last post by:
Does anybody know why unsigned char myImage; works but unsigned char myImage; does not? I think its because the second line is a value too big for unsigned char, is this ...
7
by: Jim Showalter | last post by:
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> ...
16
by: junky_fellow | last post by:
According to Section A6.6 Pointers and Integers (k & R) " A pointer to one type may be converted to a pointer to another type. The resulting pointer may cause addressing exceptions if the...
204
by: Alexei A. Frounze | last post by:
Hi all, I have a question regarding the gcc behavior (gcc version 3.3.4). On the following test program it emits a warning: #include <stdio.h> int aInt2 = {0,1,2,4,9,16}; int aInt3 =...
49
by: elmar | last post by:
Hi Clers, If I look at my ~200000 lines of C code programmed over the past 15 years, there is one annoying thing in this smart language, which somehow reduces the 'beauty' of the source code...
17
by: I.M. !Knuth | last post by:
Hi. I'm more-or-less a C newbie. I thought I had pointers under control until I started goofing around with this: ...
9
by: JoeC | last post by:
I have a question about advanced poiters. I know the basics of memory managment and pointers. That a pointer points to a memory location. I also have read that dynamic memory new is used for...
50
by: arunajob | last post by:
Hi all, If I have a piece of code something like this void main(void) { char * p1="abcdefghijklmn"; ............................................. }
41
by: simonl | last post by:
Hi, I've been given the job of sorting out a crash in our product for which we have the crash information and an avi of the event (which can't possibly match but more of that later...) (btw this...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.