Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #76631

Re: sizeof on an uninitialized pointer to a VLA

From Ben Bacarisse <ben.usenet@bsb.me.uk>
Newsgroups comp.lang.c
Subject Re: sizeof on an uninitialized pointer to a VLA
Date 2015-11-20 14:24 +0000
Organization A noiseless patient Spider
Message-ID <87mvu8rbor.fsf@bsb.me.uk> (permalink)
References <5e03af2c-3c3e-4432-bf5a-000867e5febb@googlegroups.com> <n2ljik$iqo$1@dont-email.me> <ln610wevm8.fsf@kst-u.example.com>

Show all headers | View raw


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.)

> 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."

-- 
Ben.

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


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