Redundant statement in the Standard?

Discussion in 'C Programming' started by Martin Wells, Sep 18, 2007.

  1. Martin Wells

    Martin Wells Guest

    Someone posted the following excerpt recently in relation to the
    sizeof operator:

    6.5.3.4p2: "... 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."

    The first thing that occured to me was that nothing happens when you
    evaluate a VLA. I mean what's the following supposed to do?

    {
    int arr[some_runtime_figure];

    arr;
    }

    So then I tried to think what *other* expressions could be a VLA. My
    first thought was a function, but the following won't compile for me
    with a C99 compiler, it says C99 doesn't allow to return an array from
    a function:

    int Func(void)[5]
    {
    int arr[5] = {0};

    return arr;
    }

    int main(void)
    {
    sizeof(Func());
    }

    Then I used even more of my brain and realised that I hard-coded 5
    into the function signature so I wouldn't be able to return a VLA
    anyway.

    So I'm left wondering, what kind of expression is a VLA, but which
    also DOES SOMETHING? What was the purpose of adding that little
    paragraph to the Standard?

    Would it not have been simpler to leave us with the universal "sizeof
    doesn't evaluate its operand"?

    Martin
     
    Martin Wells, Sep 18, 2007
    #1
    1. Advertising

  2. Martin Wells

    Richard Bos Guest

    Martin Wells <> wrote:

    > Someone posted the following excerpt recently in relation to the
    > sizeof operator:
    >
    > 6.5.3.4p2: "... 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."
    >
    > The first thing that occured to me was that nothing happens when you
    > evaluate a VLA.


    Consider an expression whose type is a VLA, but whose evaluation
    involves side effects. For example, given

    size_t n=some_expression();
    char arr[14][n]
    size_t i=0;

    the operation

    sizeof (arr[i++])

    would return the size of the VLA (which should be n), _and_ increment i.
    This is unfortunate, because had the declaration of n been

    #define n 93

    the very same code would have returned the size of the _non_-VLA (to
    wit, 93), and _not_ incremented i.

    The moral? Never include side-effects in the operands to sizeof, so that
    surprise is minimised.

    Richard
     
    Richard Bos, Sep 18, 2007
    #2
    1. Advertising

  3. "Richard Bos" <> a écrit dans le message de news:
    4all.nl...
    > Martin Wells <> wrote:
    >
    >> Someone posted the following excerpt recently in relation to the
    >> sizeof operator:
    >>
    >> 6.5.3.4p2: "... 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."
    >>
    >> The first thing that occured to me was that nothing happens when you
    >> evaluate a VLA.

    >
    > Consider an expression whose type is a VLA, but whose evaluation
    > involves side effects. For example, given
    >
    > size_t n=some_expression();
    > char arr[14][n]
    > size_t i=0;
    >
    > the operation
    >
    > sizeof (arr[i++])
    >
    > would return the size of the VLA (which should be n), _and_ increment i.
    > This is unfortunate, because had the declaration of n been
    >
    > #define n 93
    >
    > the very same code would have returned the size of the _non_-VLA (to
    > wit, 93), and _not_ incremented i.
    >
    > The moral? Never include side-effects in the operands to sizeof, so that
    > surprise is minimised.


    Actually the moral should be that the Standard has a defect.
    Evaluating the argument in not needed to determine the size of the VLA
    object, so why should it be mandated ?

    Conversely, if the argument is a VLA-type, some form of evaluation would be
    necessary, but we would have to define the meaning of "evaluating a
    VLA-type."

    An example of this is:

    int function();

    sizeof(char[function()]);

    But then it wouldn't be much of a problem is such an expression was left as
    invoking undefined behaviour.

    --
    Chqrlie.
     
    Charlie Gordon, Sep 18, 2007
    #3
  4. > Martin Wells <> wrote:
    >> Someone posted the following excerpt recently in relation to the
    >> sizeof operator:
    >>
    >> 6.5.3.4p2: "... 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."
    >>
    >> The first thing that occured to me was that nothing happens when you
    >> evaluate a VLA.


    (Richard Bos) writes:
    > Consider an expression whose type is a VLA, but whose evaluation
    > involves side effects. For example, given
    >
    > size_t n=some_expression();
    > char arr[14][n]
    > size_t i=0;
    >
    > the operation
    >
    > sizeof (arr[i++])
    >
    > would return the size of the VLA (which should be n), _and_ increment i.


    No, I don't think that's the case. arr[i++] is not a VLA -- it's
    a character hence sizeof would return 1 and there will be no side
    effects.

    I suppose that valid example is "sizeof(char[n])" where n is not
    a constant.

    --
    Best regards, _ _
    .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
    ..o | Computer Science, Michal "mina86" Nazarewicz (o o)
    ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
     
    Michal Nazarewicz, Sep 18, 2007
    #4
  5. Martin Wells

    Richard Bos Guest

    Michal Nazarewicz <> wrote:

    > (Richard Bos) writes:
    > > Martin Wells <> wrote:
    > >> Someone posted the following excerpt recently in relation to the
    > >> sizeof operator:
    > >>
    > >> 6.5.3.4p2: "... 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."
    > >>
    > >> The first thing that occured to me was that nothing happens when you
    > >> evaluate a VLA.

    >
    > > Consider an expression whose type is a VLA, but whose evaluation
    > > involves side effects. For example, given
    > >
    > > size_t n=some_expression();
    > > char arr[14][n]
    > > size_t i=0;
    > >
    > > the operation
    > >
    > > sizeof (arr[i++])
    > >
    > > would return the size of the VLA (which should be n), _and_ increment i.

    >
    > No, I don't think that's the case. arr[i++] is not a VLA -- it's
    > a character hence sizeof would return 1 and there will be no side
    > effects.


    Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
    arr[i++][4] would be a char.

    > I suppose that valid example is "sizeof(char[n])" where n is not
    > a constant.


    That, too, if n has side effects.

    Richard
     
    Richard Bos, Sep 18, 2007
    #5
  6. >> (Richard Bos) writes:
    >>> Consider an expression whose type is a VLA, but whose evaluation
    >>> involves side effects. For example, given
    >>>
    >>> size_t n=some_expression();
    >>> char arr[14][n]
    >>> size_t i=0;
    >>>
    >>> the operation
    >>>
    >>> sizeof (arr[i++])
    >>>
    >>> would return the size of the VLA (which should be n), _and_ increment i.


    > Michal Nazarewicz <> wrote:
    >> No, I don't think that's the case. arr[i++] is not a VLA -- it's
    >> a character hence sizeof would return 1 and there will be no side
    >> effects.


    (Richard Bos) writes:
    > Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
    > arr[i++][4] would be a char.


    Oh... sorry. You're right. :)

    --
    Best regards, _ _
    .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
    ..o | Computer Science, Michal "mina86" Nazarewicz (o o)
    ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
     
    Michal Nazarewicz, Sep 18, 2007
    #6
  7. Martin Wells

    CBFalconer Guest

    Richard Bos wrote:
    > Michal Nazarewicz <> wrote:
    >

    .... snip ...
    >>
    >> No, I don't think that's the case. arr[i++] is not a VLA -- it's
    >> a character hence sizeof would return 1 and there will be no side
    >> effects.

    >
    > Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
    > arr[i++][4] would be a char.


    You can't have an array of arrays. You can have an array of
    pointers to an array.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>


    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Sep 19, 2007
    #7
  8. In article <>,
    CBFalconer <> wrote:

    >You can't have an array of arrays. You can have an array of
    >pointers to an array.


    int x[3][5];

    declares an array of arrays. You can even have an array of VLAs,
    though they must all be the same size.

    -- Richard

    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
     
    Richard Tobin, Sep 19, 2007
    #8
  9. CBFalconer <> writes:
    > Richard Bos wrote:
    >> Michal Nazarewicz <> wrote:

    > ... snip ...
    >>>
    >>> No, I don't think that's the case. arr[i++] is not a VLA -- it's
    >>> a character hence sizeof would return 1 and there will be no side
    >>> effects.

    >>
    >> Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
    >> arr[i++][4] would be a char.

    >
    > You can't have an array of arrays.


    Incorrect, you most certainly can.

    > You can have an array of
    > pointers to an array.


    Correct (but a pointer to an array is rarely as useful as a pointer to
    the first member of an array).

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 19, 2007
    #9
  10. Martin Wells

    Richard Bos Guest

    CBFalconer <> wrote:

    > Richard Bos wrote:
    > > Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
    > > arr[i++][4] would be a char.

    >
    > You can't have an array of arrays. You can have an array of
    > pointers to an array.


    From 6.5.2.1:

    # 4 EXAMPLE Consider the array object defined by the declaration
    # int x[3][5];
    # Here x is a 3 ×5 array of ints; more precisely, x is an array of
    # three element objects, each of which is an array of five ints.

    'tis only a sample, i'faith, but a convincing one at that, marry.

    Richard
     
    Richard Bos, Sep 19, 2007
    #10
  11. Martin Wells

    Army1987 Guest

    On Tue, 18 Sep 2007 19:34:43 -0400, CBFalconer wrote:
    > You can't have an array of arrays. You can have an array of
    > pointers to an array.


    #include <stdio.h>
    int main(void)
    {
    char a[20][20];
    char ((*b[20])[20];
    printf("%lu %lu\n", (unsigned long)sizeof a,
    (unsigned long)sizeof b);
    return 0;
    }

    --
    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
     
    Army1987, Sep 19, 2007
    #11
  12. Martin Wells

    CBFalconer Guest

    Keith Thompson wrote:
    > CBFalconer <> writes:
    >> Richard Bos wrote:
    >>> Michal Nazarewicz <> wrote:

    >> ... snip ...
    >>>>
    >>>> No, I don't think that's the case. arr[i++] is not a VLA -- it's
    >>>> a character hence sizeof would return 1 and there will be no side
    >>>> effects.
    >>>
    >>> Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
    >>> arr[i++][4] would be a char.

    >>
    >> You can't have an array of arrays.

    >
    > Incorrect, you most certainly can.


    The original was dealing with an array of VLAs. I omitted the VLA
    word in my comment.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Sep 19, 2007
    #12
  13. Martin Wells

    Old Wolf Guest

    On Sep 19, 11:34 am, CBFalconer <> wrote:
    > You can't have an array of arrays. You can have an array of
    > pointers to an array.


    Is this the real CBFalconer?
     
    Old Wolf, Sep 19, 2007
    #13
  14. Martin Wells

    Richard Guest

    CBFalconer <> writes:

    > Richard Bos wrote:
    >> Michal Nazarewicz <> wrote:
    >>

    > ... snip ...
    >>>
    >>> No, I don't think that's the case. arr[i++] is not a VLA -- it's
    >>> a character hence sizeof would return 1 and there will be no side
    >>> effects.

    >>
    >> Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
    >> arr[i++][4] would be a char.

    >
    > You can't have an array of arrays. You can have an array of
    > pointers to an array.


    What total and utter nonsense. Another example of the c.l.c word games
    at their very worst.

    int multi[ROWS][COLS];

    >
    > --
    > Chuck F (cbfalconer at maineline dot net)
    > Available for consulting/temporary embedded and systems.
    > <http://cbfalconer.home.att.net>
     
    Richard, Sep 19, 2007
    #14
  15. On Wed, 19 Sep 2007 18:35:50 +0200, Richard wrote:
    > CBFalconer <> writes:
    >> You can't have an array of arrays. You can have an array of pointers
    >> to an array.

    >
    > What total and utter nonsense. Another example of the c.l.c word games
    > at their very worst.
    >
    > int multi[ROWS][COLS];


    It doesn't work as a word game. What you declared is an array of arrays.
    multi[0], in most contexts, will be converted to a pointer, but that
    doesn't mean it is one. The original claim is simply wrong.
     
    =?iso-2022-kr?q?Harald_van_D=0E=29=26=0Fk?=, Sep 19, 2007
    #15
  16. Martin Wells

    Richard Guest

    Old Wolf <> writes:

    > On Sep 19, 11:34 am, CBFalconer <> wrote:
    >> You can't have an array of arrays. You can have an array of
    >> pointers to an array.

    >
    > Is this the real CBFalconer?


    It would appear to be from the accuracy of his statements.
     
    Richard, Sep 19, 2007
    #16
  17. CBFalconer <> writes:
    > Keith Thompson wrote:
    >> CBFalconer <> writes:
    >>> Richard Bos wrote:
    >>>> Michal Nazarewicz <> wrote:
    >>> ... snip ...
    >>>>>
    >>>>> No, I don't think that's the case. arr[i++] is not a VLA -- it's
    >>>>> a character hence sizeof would return 1 and there will be no side
    >>>>> effects.
    >>>>
    >>>> Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
    >>>> arr[i++][4] would be a char.
    >>>
    >>> You can't have an array of arrays.

    >>
    >> Incorrect, you most certainly can.

    >
    > The original was dealing with an array of VLAs. I omitted the VLA
    > word in my comment.


    I think you're still mistaken. As far as I can tell, VLAs of VLAs are
    permitted.

    The following program:

    #include <stdio.h>
    int main(void)
    {
    int n = 10;
    char arr[n][n];
    printf("sizeof arr[0] = %d\n", (int)sizeof arr[0]);
    printf("sizeof arr = %d\n", (int)sizeof arr);
    return 0;
    }

    is accepted without complaint by gcc, icc, and Sun's C compiler under
    Solaris 10, and produces the output:

    sizeof arr[0] = 10
    sizeof arr = 100

    (which doesn't actually prove anything), and I don't see any such
    restriction in C99 6.7.5.2 (which doesn't really prove anything
    either; I might have missed something).

    It was also accepted without complaint by Comeau's test drive page,
    <http://www.comeaucomputing.com/pcgi-bin/compiler.html>, in strict C99
    mode (though that page doesn't give you output).

    Can you quote any wording from the standard that forbids VLAs of VLAs?

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 20, 2007
    #17
  18. Martin Wells

    CBFalconer Guest

    Keith Thompson wrote:
    > CBFalconer <> writes:
    >> Keith Thompson wrote:
    >>> CBFalconer <> writes:
    >>>

    .... snip ...
    >>>>
    >>>> You can't have an array of arrays.
    >>>
    >>> Incorrect, you most certainly can.

    >>
    >> The original was dealing with an array of VLAs. I omitted the VLA
    >> word in my comment.

    >
    > I think you're still mistaken. As far as I can tell, VLAs of VLAs
    > are permitted.


    I differ. Arrays need to be composed of equal sized objects.
    VLAs, by nature, are variable sized objects. You could have an
    array of pointers to VLAs, though.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Sep 20, 2007
    #18
  19. Martin Wells

    Chris Torek Guest

    >Keith Thompson wrote:
    >>As far as I can tell, VLAs of VLAs are permitted.


    (They are, necessarily so.)

    In article <>,
    CBFalconer <> wrote:
    >I differ. Arrays need to be composed of equal sized objects.
    >VLAs, by nature, are variable sized objects.


    This is the tricky part: while VLAs are "variable length arrays",
    each *instance* of any given VLA is fixed-size.

    VLAs of VLAs are necessary because one of the goals, perhaps even
    the primary goal, of VLAs in the first place was to allow C
    programmers to write Fortran-like functions with Fortran-like
    convenience, e.g.:

    /* perform some operation on a matrix of "double" */
    void mat_operate(size_t m, size_t n, double mat[m][n]) {
    size_t i, j;

    for (i = 0; i < m; i++)
    for (j = 0; j < n; j++)
    ... operate on mat[j] ...
    }

    When mat_operate() is called, m and n are variable, but while
    mat_operate() operates, m and n remain fixed. The size of the
    matrix "mat" is also fixed.

    (This remains true even if m and/or n are modified inside mat_operate().
    The size is, in effect, "captured" at the point the VLA is created.)

    The key sentences in my draft read:

    The size of each instance of a variable length array type
    does not change during its lifetime.

    and (in part):

    ... the size of the variable length array type does not change
    if the value of n is subsequently changed.

    >You could have an array of pointers to VLAs, though.


    You can indeed have this, as well. You can also have a VLA of
    pointers to VLAs, and so on.

    The compile-time compatibility rules for pointers to VLAs are
    quite relaxed, with the effect at runtime being undefined if the
    sizes of the variably-modified types do not match:

    void f(size_t n, double square_mat[n][n]) {
    double (*p)[rand()]; /* bad idea, for illustration only */

    p = square_mat; /* not a compile-time error */
    ...
    }

    The effect is undefined unless n happens to be equal to the
    value rand() returns. In practice, in a real C compiler, if
    rand() returns a number that does not match n, p[0][j] "works
    right" but p[j] misbehaves: If we were to capture the
    number that came out of the rand() call, e.g., via:

    size_t x;
    double (*p)[x = rand()];

    instead, then p[j] is roughly equivalent to mat[0][i * x + j]
    as long as no subscript checking occurs. (Of course, because of
    the undefined behavior, the compiler can make various assumptions
    and optimize this particular weirdness into *other* weirdness.
    For instance, it might make the assumption that x must necessarily
    equal n, hence remove x from the runtime image and use the saved
    n -- so that p[j] accesses mat[j] after all!)
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Sep 20, 2007
    #19
  20. CBFalconer <> writes:
    > Keith Thompson wrote:
    >> CBFalconer <> writes:
    >>> Keith Thompson wrote:
    >>>> CBFalconer <> writes:
    >>>>

    > ... snip ...
    >>>>>
    >>>>> You can't have an array of arrays.
    >>>>
    >>>> Incorrect, you most certainly can.
    >>>
    >>> The original was dealing with an array of VLAs. I omitted the VLA
    >>> word in my comment.

    >>
    >> I think you're still mistaken. As far as I can tell, VLAs of VLAs
    >> are permitted.

    >
    > I differ. Arrays need to be composed of equal sized objects.
    > VLAs, by nature, are variable sized objects. You could have an
    > array of pointers to VLAs, though.


    You snipped the part where I asked you to provide a citation from the
    standard to support your claim. You also snipped the example
    demonstrating a VLA of VLAs.

    The size of a VLA is fixed at runtime when it's created, and all the
    elements of an array of VLAs must have the same size.

    If you have a specific reason to think this isn't allowed, I'd love to
    hear it (and somebody should submit bug reports against the four
    different compilers that didn't complain about VLAs of VLAs).

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 20, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Neil Zanella
    Replies:
    15
    Views:
    939
    Jim Wu
    Dec 18, 2003
  2. =?Utf-8?B?Sm9obiBXYWxrZXI=?=

    Redundant ASP.NET SQL command executions.

    =?Utf-8?B?Sm9obiBXYWxrZXI=?=, Oct 7, 2004, in forum: ASP .Net
    Replies:
    7
    Views:
    382
    Hermit Dave
    Oct 11, 2004
  3. =?Utf-8?B?cm9kY2hhcg==?=

    is this redundant...

    =?Utf-8?B?cm9kY2hhcg==?=, Sep 16, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    429
    =?Utf-8?B?cm9kY2hhcg==?=
    Sep 16, 2005
  4. JustAnotherGuy

    Redundant links

    JustAnotherGuy, Dec 28, 2003, in forum: HTML
    Replies:
    9
    Views:
    543
  5. Benjamin Rutt

    finding redundant #includes to shorten compile time

    Benjamin Rutt, Feb 5, 2004, in forum: C Programming
    Replies:
    15
    Views:
    1,030
    CBFalconer
    Feb 6, 2004
Loading...

Share This Page