Re: The canonical clc malloc idiom
- From: Army1987 <army1987@xxxxxxxxx>
- Date: Thu, 20 Sep 2007 13:48:17 +0200
On Wed, 19 Sep 2007 21:20:17 -0700, Keith Thompson wrote:
The comp.lang.c-recommended way to invoke malloc() is, of course:But it is a strong clue that it doesn't actually read from *ptr,
some_type *ptr;
ptr = malloc(count * sizeof *ptr);
But what if (in C99 only) ptr is a pointer to a VLA (variable-length
array) type? Consider this:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n = 10;
typedef char VLA[n];
VLA *ptr = NULL;
ptr = malloc(3 * sizeof *ptr);
printf("sizeof *ptr = %d\n", (int)sizeof *ptr);
return 0;
}
As far as I can tell, this is legal in C99. The operand of sizeof in
the malloc call is *ptr, which is of a variable-length array type,
which means, according to C99 6.5.3.4p2, that it's evaluated. Since
ptr is a null pointer at that point, evaluating *ptr invokes undefined
behavior.
I'm not suggesting that we should drop the clc-approved method for the
normal case; I suspect that malloc calls involving VLA types are going
to be vanishingly rare. It's just an interesting quirk of the
language.
Incidentally, the above program compiles and executes without error
under gcc in its C99ish mode. That doesn't prove anything, since it's
one possible consequence of UB.
since that would be likely to cause a SIGSEGV. I tried declaring
ptr as volatile VLA *, but it still doesn't crash. Whereas the UB
allows it not to actually read from there, the compiler would need
to do a serious amount of language lawyering to behave like that.
A more likely explanation is in http://gcc.gnu.org/c99status.html,
where the support for VLAs is marked as "Broken".
In the C99 rationale I can read:
Side effects in variable length array size expressions are guaranteed to be produced, except in
one context. If a size expression is part of the operand of a sizeof operator, and the result of
that sizeof operator does not depend on the value of the size expression, then it is unspecified
10 whether side effects are produced. In the following example:
{
int n = 5;
int m = 7;
size_t sz = sizeof(int (*)[n++]);
15 }
the value of the result of the sizeof operator is the same as in:
{
int n = 5;
int m = 7;
20 size_t sz = sizeof(int (*)[m++]);
}
Since the value stored in sz does not depend on the size expression, the side effect in n++ is
not guaranteed to occur. Requiring the side effect introduced a burden on some
implementations. Since side effects in this context seemed to have limited utility and are not
25 perceived to be a desired coding style, the Committee decided to make it unspecified whether
these size expressions are actually evaluated.
IOW, "don't do that".
--
Army1987 (Replace "NOSPAM" with "email")
If you're sending e-mail from a Windows machine, turn off Microsoft's
stupid “Smart Quotes” feature. This is so you'll avoid sprinkling garbage
characters through your mail. -- Eric S. Raymond and Rick Moen
.
- Follow-Ups:
- Re: The canonical clc malloc idiom
- From: Keith Thompson
- Re: The canonical clc malloc idiom
- References:
- The canonical clc malloc idiom
- From: Keith Thompson
- The canonical clc malloc idiom
- Prev by Date: Re: Suggest microcontroller and compiler
- Next by Date: Re: Suggest microcontroller and compiler
- Previous by thread: Re: The canonical clc malloc idiom
- Next by thread: Re: The canonical clc malloc idiom
- Index(es):
Relevant Pages
|
|