Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | Re: sizeof on an uninitialized pointer to a VLA |
| Date | 2015-11-20 18:29 -0800 |
| Organization | None to speak of |
| Message-ID | <lnsi40axv9.fsf@kst-u.example.com> (permalink) |
| References | <5e03af2c-3c3e-4432-bf5a-000867e5febb@googlegroups.com> <n2ljik$iqo$1@dont-email.me> <ln610wevm8.fsf@kst-u.example.com> <87mvu8rbor.fsf@bsb.me.uk> |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> James Kuyper <jameskuyper@verizon.net> writes:
>>> On 11/19/2015 02:39 PM, John Bode wrote:
>>>> I've been using the following idiom a lot to dynamically allocate
>>>> 2D arrays:
>>>>
>>>> T (*arr)[N] = malloc( sizeof *arr * M );
>>>
>>> M=>N?
>>>
>>>> Works great where N is known at compile time. However, I've also been
>>>> applying it to VLAs, like so:
>>>>
>>>> size_t rows;
>>>> size_t cols;
>>>> ...
>>>> T (*arr)[rows] = malloc( sizeof *arr * cols );
>>>>
>>>> I've never had any issues, but...does this count as undefined behavior?
>>>> `sizeof` evaluates the operand when it's a VLA, but what does "evaluate"
>>>> mean in this context? Is it trying to dereference the pointer, or is it
>>>> simply determining the size of *any* object the pointer may refer to?
>>>
>>> The key thing about VLA types is that their sized depends upon the value
>>> of one or more expressions, in this case the relevant expression is
>>> "rows". The evaluation it's talking about is the evaluation of that
>>> expression. Unless the expression has side-effects (for example,
>>> rows++), the possibility of it being evaluated is not an issue you need
>>> to worry about.
>>
>> No, the expression `rows` is not evaluated.
>>
>> Consider:
>>
>> size_t rows = 10;
>> char vla[rows];
>> rows = 20;
>> sizeof vla;
>>
>> `sizeof vla` is 10, not 20. Evaluating `rows` is not just
>> unnecessary; it gives the wrong result.
>>
>> I think the standard is just being sloppy to the point of being
>> incorrect here. For non-VLA types, `sizeof expr` and `sizeof
>> (typename)` are evaluated at compile time.
>
> I agree that the wording probably does not say what was intended.
> Unfortunately it's not really unclear so what should a conforming
> compiler do?
>>
>> For an expression of a VLA type, `sizeof expr` has to be determined
>> at run time, but the only thing that actually needs to be evaluated
>> is the stored value of whatever anonymous object the compiler
>> uses to remember the size (with perhaps some other computation if,
>> for example, the stored value is an element count). Neither the
>> expression that determined the size (whose value may not be the same)
>> nor the value of the array object (which consists of the values of
>> its elements) actually needs to be evaluated.
>>
>> For `sizeof` applied to a parenthesized VLA type, any expressions
>> that are part of the type name have to be evaluated. For example,
>> in `sizeof (char[func()])`, the function has to be called and any
>> side effects must occur; similarly for `sizeof (char[n++])`.
>
> But, as I am sure you know, the wording in the standard goes further.
> If we replace *arr with arr[0] but with the 0 being produced by a
> function call:
>
> sizeof arr[f()]
>
> then the wording says that f must be called. gcc obliges but clang does
> not. (No implementation is required to go any further and actually
> access the as yet non-existent array, but the standard, as worded,
> implies that the above, and the original, are undefined.)
Interesting point. Here's an example:
#include <stdio.h>
int zero(void) {
puts("zero()");
return 0;
}
int main(void) {
int n = 10;
char vla[n][n];
printf("sizeof vla[zero()] = %zu\n", sizeof vla[zero()]);
}
The output using every version of gcc and clang I've tried is:
zero()
sizeof vla[zero()] = 10
The sizeof computation is correct, but it *could* have been determined
without calling the function. As far as I can tell, the value returned
by the call to zero() can have no effect on the result of the sizeof
computation.
>> The standard doesn't actually manage to say all this, but I think
>> that's the only reasonable interpretation of the intent.
>
> As you say, the intent may well have been to limit evaluation to
> expressions contained in type names of VLAs, but it certainly doesn't
> say that, and at least one implementation has taken the literal meaning.
>
> Maybe rather than this:
>
> "If the type of the operand is a variable length array type, the
> operand is evaluated; otherwise, the operand is not evaluated and the
> result is an integer constant."
>
> what was meant was this:
>
> "If the operand is a variable length array type name, any expressions
> in the operand are evaluated; otherwise, the operand is not evaluated
> and the result is an integer constant."
The result of `sizeof vla_object` is not an integer constant. (Aside:
"integer constant" is a poor choice of words, since that phrase has a
different meaning.)
The type of the operand to sizeof is known at compile time, and
I believe that the size of that type can always be determined
without evaluating anything other than the values of anonymous
compiler-generated objects (or whatever mechanism the implementation
uses to remember the size of a VLA type).
I suggest something like:
If the operand is a parenthesized variable length array type name,
any expressions in the operand are evaluated. Otherwise, the
operand is not evaluated. The result is constant unless the
type of the operand is a variable length array type.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
sizeof on an uninitialized pointer to a VLA John Bode <jfbode1029@gmail.com> - 2015-11-19 11:39 -0800
Re: sizeof on an uninitialized pointer to a VLA supercat@casperkitty.com - 2015-11-19 12:09 -0800
Re: sizeof on an uninitialized pointer to a VLA "A. Bolmarcich" <aggedor@earl-grey.cloud9.net> - 2015-11-19 21:40 +0000
Re: sizeof on an uninitialized pointer to a VLA supercat@casperkitty.com - 2015-11-19 13:50 -0800
Re: sizeof on an uninitialized pointer to a VLA James Kuyper <jameskuyper@verizon.net> - 2015-11-19 17:50 -0500
Re: sizeof on an uninitialized pointer to a VLA supercat@casperkitty.com - 2015-11-19 15:31 -0800
Re: sizeof on an uninitialized pointer to a VLA Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-20 01:09 +0000
Re: sizeof on an uninitialized pointer to a VLA supercat@casperkitty.com - 2015-11-19 19:10 -0800
Re: sizeof on an uninitialized pointer to a VLA Keith Thompson <kst-u@mib.org> - 2015-11-20 03:52 -0800
Re: sizeof on an uninitialized pointer to a VLA Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-20 14:24 +0000
Re: sizeof on an uninitialized pointer to a VLA supercat@casperkitty.com - 2015-11-20 10:25 -0800
Re: sizeof on an uninitialized pointer to a VLA Keith Thompson <kst-u@mib.org> - 2015-11-20 18:29 -0800
Re: sizeof on an uninitialized pointer to a VLA Ian Collins <ian-news@hotmail.com> - 2015-11-21 16:35 +1300
Re: sizeof on an uninitialized pointer to a VLA Keith Thompson <kst-u@mib.org> - 2015-11-20 20:24 -0800
Re: sizeof on an uninitialized pointer to a VLA Ian Collins <ian-news@hotmail.com> - 2015-11-21 17:38 +1300
Re: sizeof on an uninitialized pointer to a VLA Keith Thompson <kst-u@mib.org> - 2015-11-20 21:08 -0800
Re: sizeof on an uninitialized pointer to a VLA Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-21 10:46 +0000
Re: sizeof on an uninitialized pointer to a VLA Keith Thompson <kst-u@mib.org> - 2015-11-21 03:26 -0800
Re: sizeof on an uninitialized pointer to a VLA Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-21 12:46 +0000
Re: sizeof on an uninitialized pointer to a VLA Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-21 14:01 +0000
Re: sizeof on an uninitialized pointer to a VLA supercat@casperkitty.com - 2015-11-21 09:02 -0800
Re: sizeof on an uninitialized pointer to a VLA Keith Thompson <kst-u@mib.org> - 2015-11-21 12:09 -0800
csiph-web