[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