Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #148310
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | Re: sizeof object got by dereferencing uniniitalized pointer |
| Date | 2019-11-30 11:19 +0000 |
| Organization | A noiseless patient Spider |
| Message-ID | <875zj1393a.fsf@bsb.me.uk> (permalink) |
| References | (8 earlier) <86eexr8qlh.fsf@linuxsc.com> <87v9r33211.fsf@bsb.me.uk> <86k17i7kuh.fsf@linuxsc.com> <87pnha2vhx.fsf@bsb.me.uk> <wwlEF.120234$P37.83682@fx33.iad> |
Richard Damon <Richard@Damon-Family.org> writes:
> On 11/29/19 5:00 PM, Ben Bacarisse wrote:
>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>
>>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>>
>>>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>>>
>>>>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>>>>
>>>>>> Thiago Adams <thiago.adams@gmail.com> writes:
>>>>>> <cut>
>>>>>>
>>>>>>> Only when applied to variably types, sizeof is in runtime.
>>>>>>>
>>>>>>> int n = 10;
>>>>>>>
>>>>>>> int(*buf)[n] = malloc(sizeof(int) * n);
>>>>>>
>>>>>> Why would you not write
>>>>>>
>>>>>> int (*buf)[n] = malloc(sizof *buf);
>>>>>>
>>>>>> ?
>>>>>
>>>>> Perhaps because, technically speaking, the right-hand side here
>>>>> has undefined behavior?
>>>>
>>>> Yes, it has. That has always puzzled me. Do you think that this usage
>>>> was specifically being ruled out, or is it a casualty of having made an
>>>> overly simple decision[1]?
>>>
>>> I have now looked into this further and can offer a more informed
>>> answer. More below.
>>>
>>>> This whole areas makes me uneasy. I've never been able to find a
>>>> reasonable example where an expression operand of sizeof needs to be
>>>> evaluated[2] (as the standard mandates) but most compilers evaluate f in
>>>>
>>>> sizeof (int[f()])
>>>>
>>>> despite the standard not explaining what it means to evaluate a type
>>>> (though its not hard to guess what is intended). Do the rules make
>>>> sense to you? [I note your comment about _Generic_ but taking
>>>> it out because it doesn't bear on what I have to say.]
>>>
>>> The rules now make sense to me. The authors wanted to be sure (or
>>> so I believe, in case that needs saying) that they didn't miss any
>>> corner cases, and so used general wording.
>>
>> I didn't say what I meant, sorry. I wanted to ask if you think the
>> rules are the right ones. I feel the sacrifice (to undefined behaviour)
>> of patterns like
>>
>> memset(ptr, 0, sizeof *ptr);
>>
>> to be unfortunate. Mind you, VLAs, and the even more useful variably
>> modified types, have been thrown under the bus anyway.
>>
>
> That isn't a good example, as if ptr isn't valid the fact that sizeof
> might generate UB pales to the effect of doing a memset on what it
> points to will do.
Yes, thanks. A chain of edits led to this silly example because I
wanted something other than
> ptr = malloc(sizeof *ptr);
which had already come up. I thought I'd used memcpy(d, s, sizeof *s)
but then edited it to something daft!
>
> on the other hand would be a reasonable example of what I think you are
> referring to. Making this technically Undefined behavior is regrettable,
> but if the choice is between making it UB, with the possibility that the
> implementation can define that it just works as expected, or having the
> standard make a promise that implementations can't meet, and thus be
> defective (or maybe they can do it but at great inefficiency) then it
> makes sense to err initially on the side of creating UB, and if desired,
> later the rules on the implementation can be tightened up, and things
> are backwards compatible, while adding restrictions on promises would be
> a breaking change.
>
>>> They did think about
>>> needless evaluation in 'sizeof' operands, and the Standard does
>>> have a provision which talks about that; in fact that provision
>>> evolved while C99 was being written.
>>
>> I would have argued for a limited form of evaluation -- evaluation
>> sufficient to determine the type. I think the rules would not be too
>> complicated, and it would be the natural place to specify what
>> "evaluating" a type name means.
>>
>>> (If anyone cares they might
>>> want to compare n869 to later versions of the C99 standard.)
>>>
>>> Now, I hear you ask, _what_ corner cases? Here is one, taken from
>>> my recent reponse to Keith Thompson:
>>>
>>> int foo = sizeof *(int (*)[ ident( 1 ) ]){ &something };
>>>
>>> This declaration is legal C99, provided of course there are
>>> suitable declarations for the identifiers 'something' and 'ident'
>>> in scope. The operand is an expression, not a type name, although
>>> of course the expression does have a type name within it. The
>>> operand expression needs to be evaluated, at least in part, in
>>> order to determine the result of the sizeof operator.
>>
>> The same effect can be achieved without a compound literal by using a
>> cast. Is there a subtle point I'm missing that relies on the CL?
>
> Yes, a cast can do the same too.
>>
>>> Rather than
>>> concoct some carefully chosen language that does some sort of
>>> partial evalution for just those subexpressions that are needed
>>> to produce the result, the authors chose the simple rule that
>>> any VLA operand argument is evaluated. That decision has some
>>> unfortunate consequences for undefined behavior, but in the 1990s
>>> there wasn't as much hysteria regarding undefined behavior as
>>> there is now.
>>
>> Maybe " evaluation sufficient to determine the type" is more complicated
>> than I imagine. I wonder if it was every considered.
>
> It may be that such wording seems imprecise. For instance, if the
> expression includes the comma operator, does the fact that the first
> value not effect the results mean it doesn't get evaluated? what if it
> includes a function call so there is a possibility of side effects? What
> if it somehow knows that it doesn't have side effects, but might
> invoke UB?
If the second operand is not a variable length array type, then the
first operand need not be evaluated. But when there is a variably
modified type in the second, you raise an interesting point -- to what
extent should the standard specify when evaluation can be skipped? For
example, in
int n = 42, a[n];
return sizeof (f(), a);
f() can't effect the type, not even if the call were sizeof (f(&n), a).
But in
extern int n;
n = 42;
return sizeof *(f(), (int (*)[n])0);
it can. I'd go for the simplest rule: evaluate if second operand is a
variably modified type.
As usual with simple rules, it's starting to get complicated!
--
Ben.
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
sizeof object got by dereferencing uniniitalized pointer "V.Subramanian, India" <subramanian100in@yahoo.com> - 2019-11-28 05:20 -0800
Re: sizeof object got by dereferencing uniniitalized pointer Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2019-11-28 05:37 -0800
Re: sizeof object got by dereferencing uniniitalized pointer mark.bluemel@gmail.com - 2019-11-28 05:59 -0800
Re: sizeof object got by dereferencing uniniitalized pointer David Brown <david.brown@hesbynett.no> - 2019-11-28 15:51 +0100
Re: sizeof object got by dereferencing uniniitalized pointer Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2019-11-28 07:27 -0800
Re: sizeof object got by dereferencing uniniitalized pointer Herbert Rosenau <nospam@hrosenau.de> - 2019-11-28 17:28 +0100
Re: sizeof object got by dereferencing uniniitalized pointer Thiago Adams <thiago.adams@gmail.com> - 2019-11-28 08:51 -0800
Re: sizeof object got by dereferencing uniniitalized pointer Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-28 17:36 +0000
Re: sizeof object got by dereferencing uniniitalized pointer Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-11-28 16:37 -0800
Re: sizeof object got by dereferencing uniniitalized pointer Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-29 01:27 +0000
Re: sizeof object got by dereferencing uniniitalized pointer Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-11-28 17:47 -0800
Re: sizeof object got by dereferencing uniniitalized pointer Richard Damon <Richard@Damon-Family.org> - 2019-11-28 21:16 -0500
Re: sizeof object got by dereferencing uniniitalized pointer Keith Thompson <kst-u@mib.org> - 2019-11-29 00:38 -0800
Re: sizeof object got by dereferencing uniniitalized pointer Richard Damon <Richard@Damon-Family.org> - 2019-11-29 09:03 -0500
Re: sizeof object got by dereferencing uniniitalized pointer Keith Thompson <kst-u@mib.org> - 2019-11-29 13:15 -0800
Re: sizeof object got by dereferencing uniniitalized pointer Keith Thompson <kst-u@mib.org> - 2019-11-29 13:38 -0800
Re: sizeof object got by dereferencing uniniitalized pointer Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-11-29 07:09 -0800
Re: sizeof object got by dereferencing uniniitalized pointer Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-11-29 06:10 -0800
Re: sizeof object got by dereferencing uniniitalized pointer Richard Damon <Richard@Damon-Family.org> - 2019-11-29 11:12 -0500
Re: sizeof object got by dereferencing uniniitalized pointer Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-12-01 09:32 -0800
Re: sizeof object got by dereferencing uniniitalized pointer Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-11-29 07:39 -0800
Re: sizeof object got by dereferencing uniniitalized pointer Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-29 22:00 +0000
Re: sizeof object got by dereferencing uniniitalized pointer Richard Damon <Richard@Damon-Family.org> - 2019-11-29 22:40 -0500
Re: sizeof object got by dereferencing uniniitalized pointer Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-30 11:19 +0000
Re: sizeof object got by dereferencing uniniitalized pointer Richard Damon <Richard@Damon-Family.org> - 2019-11-30 09:01 -0500
Re: sizeof object got by dereferencing uniniitalized pointer Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-12-01 10:28 -0800
Re: sizeof object got by dereferencing uniniitalized pointer Richard Damon <Richard@Damon-Family.org> - 2019-11-28 12:49 -0500
Re: sizeof object got by dereferencing uniniitalized pointer Thiago Adams <thiago.adams@gmail.com> - 2019-11-28 11:26 -0800
Re: sizeof object got by dereferencing uniniitalized pointer Richard Damon <Richard@Damon-Family.org> - 2019-11-28 17:19 -0500
Re: sizeof object got by dereferencing uniniitalized pointer Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-11-28 17:26 -0800
Re: sizeof object got by dereferencing uniniitalized pointer Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-28 22:34 +0000
Re: sizeof object got by dereferencing uniniitalized pointer Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-28 17:34 +0000
You gotta wonder why people say things like this! (Was: sizeof object got by dereferencing uniniitalized pointer) gazelle@shell.xmission.com (Kenny McCormack) - 2019-11-28 17:19 +0000
Re: sizeof object got by dereferencing uniniitalized pointer Keith Thompson <kst-u@mib.org> - 2019-11-28 14:55 -0800
Re: sizeof object got by dereferencing uniniitalized pointer "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2019-11-30 15:28 -0800
csiph-web