Brace-enclosed array initialisers

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Paul Jackson

    Brace-enclosed array initialisers

    Here's a brace-enclosed initialiser for a 3D array:

    int a4[2][3][4] = {
    { 1, 2, 3, 4, {5, 6, 7 }, },
    { {13, 14, 15 }, 17, 18, 19, 20, {21, 22, 23, 24} }};

    gcc produces some warnings when compiling this, but sets a4 to this,
    which is what I'd expect:

    { { 1 2 3 4 } { 5 6 7 0 } {0 0 0 0 } }
    { {13 14 15 0 } {17 18 19 20 } {21 22 23 24 } }

    It gets more interesting if I leave out initialiser '20':

    int a4[2][3][4] = {
    { 1, 2, 3, 4, {5, 6, 7 }, },
    { {13, 14, 15 }, 17, 18, 19, {21, 22, 23, 24} }};

    gcc now produces lots more warnings, and sets a4 to this:

    { { 1 2 3 4 } { 5 6 7 0 } { 0 0 0 0 } }
    { {13 14 15 0 } {17 18 19 21 } { 0 0 0 0 } }

    Any ideas on what the 'correct' behaviour here should be? I've only
    checked 6.7.8 in the C99 spec, but this seems to be wrong. I suspect
    that either reporting an error or setting a4 to

    { { 1 2 3 4 } { 5 6 7 0 } { 0 0 0 0 } }
    { {13 14 15 0 } {17 18 19 0 } {21 22 23 24 } }

    would have better.

    Thanks -

    Paul
  • Victor Bazarov

    #2
    Re: Brace-enclosed array initialisers

    Paul Jackson wrote:
    Here's a brace-enclosed initialiser for a 3D array:
    >
    int a4[2][3][4] = {
    { 1, 2, 3, 4, {5, 6, 7 }, },
    { {13, 14, 15 }, 17, 18, 19, 20, {21, 22, 23, 24} }};
    >
    gcc produces some warnings when compiling this, but sets a4 to this,
    which is what I'd expect:
    >
    { { 1 2 3 4 } { 5 6 7 0 } {0 0 0 0 } }
    { {13 14 15 0 } {17 18 19 20 } {21 22 23 24 } }
    >
    It gets more interesting if I leave out initialiser '20':
    >
    int a4[2][3][4] = {
    { 1, 2, 3, 4, {5, 6, 7 }, },
    { {13, 14, 15 }, 17, 18, 19, {21, 22, 23, 24} }};
    >
    gcc now produces lots more warnings, and sets a4 to this:
    >
    { { 1 2 3 4 } { 5 6 7 0 } { 0 0 0 0 } }
    { {13 14 15 0 } {17 18 19 21 } { 0 0 0 0 } }
    >
    Any ideas on what the 'correct' behaviour here should be? I've only
    checked 6.7.8 in the C99 spec, but this seems to be wrong. I suspect
    that either reporting an error or setting a4 to
    >
    { { 1 2 3 4 } { 5 6 7 0 } { 0 0 0 0 } }
    { {13 14 15 0 } {17 18 19 0 } {21 22 23 24 } }
    >
    would have better.
    The point of the definition (not sure about C99, too lazy to check,
    using C++03, as you ought to) is that in your example with '20' left
    out, the "17, 18, 19" fill the row a4[1][1], and since they are not
    enclosed in their own braces, the following curly brace (before the
    '21') is supposed to enclose the initialiser list for a4[1][1][3].
    AFAICT, since there are more initialisers in the braced list starting
    with '21', the entire initialiser is ill-formed. GCC lets it slide,
    apparently, and simply ignores '22, 23, 24' initialising a4[1][1][3]
    with only '21'. The rest of the array it leaves uninitialised. And
    did you try to use 'strict' mode?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask


    Comment

    • Flash Gordon

      #3
      Re: Brace-enclosed array initialisers

      Victor Bazarov wrote, On 02/05/08 13:21:
      Paul Jackson wrote:
      >Here's a brace-enclosed initialiser for a 3D array:
      >>
      >int a4[2][3][4] = {
      > { 1, 2, 3, 4, {5, 6, 7 }, },
      > { {13, 14, 15 }, 17, 18, 19, 20, {21, 22, 23, 24} }};
      >>
      >gcc produces some warnings when compiling this, but sets a4 to this,
      >which is what I'd expect:
      It is, of course, allowed to produce warnings.
      > { { 1 2 3 4 } { 5 6 7 0 } {0 0 0 0 } }
      > { {13 14 15 0 } {17 18 19 20 } {21 22 23 24 } }
      >>
      >It gets more interesting if I leave out initialiser '20':
      >>
      >int a4[2][3][4] = {
      > { 1, 2, 3, 4, {5, 6, 7 }, },
      I think this part is correct. I believe that footnote 129 makes it
      somewhat clearer.
      > { {13, 14, 15 }, 17, 18, 19, {21, 22, 23, 24} }};
      I think that this part should produce a diagnostic.
      >gcc now produces lots more warnings, and sets a4 to this:
      >>
      > { { 1 2 3 4 } { 5 6 7 0 } { 0 0 0 0 } }
      The above would have been correct.
      > { {13 14 15 0 } {17 18 19 21 } { 0 0 0 0 } }
      >Any ideas on what the 'correct' behaviour here should be? I've only
      >checked 6.7.8 in the C99 spec, but this seems to be wrong. I suspect
      >that either reporting an error or setting a4 to
      >>
      > { { 1 2 3 4 } { 5 6 7 0 } { 0 0 0 0 } }
      > { {13 14 15 0 } {17 18 19 0 } {21 22 23 24 } }
      >>
      >would have better.
      >
      The point of the definition (not sure about C99, too lazy to check,
      using C++03, as you ought to) is that in your example with '20' left
      out, the "17, 18, 19" fill the row a4[1][1], and since they are not
      enclosed in their own braces, the following curly brace (before the
      '21') is supposed to enclose the initialiser list for a4[1][1][3].
      AFAICT, since there are more initialisers in the braced list starting
      with '21', the entire initialiser is ill-formed. GCC lets it slide,
      apparently, and simply ignores '22, 23, 24' initialising a4[1][1][3]
      with only '21'. The rest of the array it leaves uninitialised.
      In C the rest of the array is definitely *not* left uninitialised. If
      you initialise part of an aggregate type (e.g. an array) then the C
      standard specifies that all members are initialised. The only exception
      to this is unnamed members of a structure objects.

      I suspect the rules are similar for C++.
      And
      did you try to use 'strict' mode?
      Yes, always worth using "-ansi -pedantic" or "-std=c99 -pedantic" if you
      want as close as it comes to C99 conformance. See
      http://gcc.gnu.org/c99status.html for information on C99 conformance.
      --
      Flash Gordon

      Comment

      Working...