help-flex
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bug(s) in 2.5.19 skel.c


From: Bruce Lilly
Subject: Re: bug(s) in 2.5.19 skel.c
Date: Tue, 17 Sep 2002 09:20:55 -0400
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020529

Hans-Bernhard Broeker wrote:
On Mon, 16 Sep 2002, Bruce Lilly wrote:


There is not even a theoretical problem with calloc or
memset there, as ANSI/ISO C section 6.2.2.3 clearly states
that a null pointer has value 0.


Wrong. There definitely is a problem, and particularly with pointers. Calling memset() or calloc() creates "all bytes zero". Which may seem to
be equivalent to "value zero" for the NULL pointer --- but it isn't,
because there is no fixed predefined mapping between pointers and
integers, including the integer zero.

No, 6.2.2.3 specifically states that there is a mapping from
an integral value of zero to a null pointer.  See that text
or K&R 2nd edition (ANSI C) p. 102.

Regarding integral types, the requirements of ANSI/ISO C section
6.1.2.5 means that for all practical purposes a zero valued integer of
any size will be all zero bits,


There's no such section in the C9x draft I have here.  Could you give the
title of that section so I can look it up?

If you're looking at a draft, you're not looking at the standard.
The title of 6.1.2.5 in the 1990 standard (a.k.a. C90) is "Types".
One requirement for integral types is that the representation of
nonnegative values for signed and unsigned types of the same size
be identical. That includes zero of course.  And the only reasonable
choices that meet that requirement have zero represented as all
zero bits.

C9x now explicitly
says that representations may have padding bits, and that certain contents
of these bits could well cause the CPU to trap if you access the value by
any means other than as a collection of bytes.

memset specifically deals with a collection of bytes, setting each
member of that collection to the value of its second argument as
an unsigned char.

Note that K&R 2nd ed. p. 167 gives the following code snippet:

int *ip;
ip = (int *) calloc(n, sizeof(int));

which is exactly what's being discussed here, viz.
initialization of a pointer via calloc.

There's another issue: code maintainability.

struct foo {
        struct foo *bar;
        /* ... */
}.

can be initialized by

struct foo *x = (struct foo *)calloc(1, sizeof(struct foo));

and that will work (after recompiling) without change if
elements are added to or removed from struct foo's definition.
Likewise for

memset(x, 0, sizeof(struct foo));

The alternatives which you suggested would almost certainly
lead to something remaining uninitialized or to memory
corruption as the structure definition is changed over the
course of time,  In the case of flex, as John mentioned,
the structure in question has elements which depend on
options and on the specific lexical patterns being matched.
Having code which is known to work on all existing
implementations *and* which is robust w.r.t. maintenance is
far preferable to code designed to accomodate some unspecified
hypothetical architecture which nobody can provide an example
of, but which is quite fragile as the code evolves (or w.r.t.
options and pattern specifics).





reply via email to

[Prev in Thread] Current Thread [Next in Thread]