[splint-discuss] Tell me more about @only@

Michael Wojcik Michael.Wojcik at Microfocus.com
Thu Jan 14 06:31:23 PST 2010


And while we're at it...

> From: splint-discuss-bounces at cs.virginia.edu [mailto:splint-discuss-
> bounces at cs.virginia.edu] On Behalf Of Bill Pringlemeir
> Sent: Wednesday, 13 January, 2010 16:18
> 
> On 13 Jan 2010, m at alanny.ru wrote:
> 
> > struct my_struct {
> > int n; /* doesn't matter */
> > /*@null@*/ struct my_struct *next;
> > }
> 
> > new_item = (struct my_struct *) malloc (sizeof (struct my_struct));

Dump the cast. Unless this code MUST be compiled as both C and C++, the
cast is unnecessary and can hide errors. Also, it's better to use the
size of the target of the assignment rather than assuming its type:

	new_item = malloc(sizeof *new_item);

That's also shorter and cleaner.

> The 'out' parameter means that things have yet to be defined.
> memset's return value might also be used if you insist on that,
> 
>    new_item = memset(new_item, 0, sizeof(*new_item));
> 
> Using memset is generally not the best as zero may not be appropriate
> in all circumstances.

Nor is there any guarantee that all-bits-zero is a null pointer
representation. C guarantees that a literal zero will be converted to a
null pointer value in a pointer context, but not that all-bits-zero is a
valid null pointer. It could be a trap representation. (The same goes
for floating-point types.)

Because of sloppy programming and widespread use of calloc (which really
only persists in the standard library for historical reasons - there's
no good reason to ever use it), pretty much all implementations accept
all-bits-zero as a null pointer representation. But relying on that is
sloppiness.

The best way to initialize a new dynamically-allocated structure is with
structure copy, from a static, const structure that's implicitly
initialized correctly.

In the header:

	struct my_struct = { ... };
	static const struct my_struct my_struct0 = {0};

In the function:

	struct my_struct *new_struct;
	new_struct = malloc(sizeof *new_struct);
	*new_struct = my_struct0;

The {0} initializer always initializes the entire object (including all
of aggregate types) to appropriate 0 representations: integers to 0,
floating point fields to 0.0, pointers to a null pointer. (The "0"
itself serves as the initializer for the first field, and all following
fields get an implicit "0" initializer value.)

Of course, here the {0} is redundant, since it's the default initializer
for an object with static storage duration; but it serves as
documentation and it's a place where you can put different
initialization values if you need to, as Bill suggested.


-- 
Michael Wojcik
Principal Software Systems Developer, Micro Focus




More information about the splint-discuss mailing list