Compound literals and VLA's

Discussion in 'C Programming' started by William Ahern, Aug 24, 2005.

  1. So, GCC 4.01 is giving errors that GCC 3.3 did not, and I'm thinking they've
    gone overboard with their new type checking infrastructure.

    Here's the supposedly offending code (no laughing or grimacing, please ;)

    char *s, *s1;

    s1 = strcpy((char [strlen(s) + 1]){ },s);

    and GCC 4.01's error messages

    error: compound literal has variable size
    error: empty scalar initializer
    error: (near initialization for `(anonymous)')

    First, is it really illegal to define a variable size for the compound array
    literal? Do compound literals and VLA's not mix? If I store the array length
    in a variable I get the same error.

    Second, what is up with "empty scalar initializer"? If I add an explicit
    zero--{ 0 }--the error obviously goes away. Does the "as if zero" rule not
    apply if no initializers are given?

    I realize GCC behavior is off-topic, but I'm curious what the conensus is on
    the proper behavior.

    - Bill
     
    William Ahern, Aug 24, 2005
    #1
    1. Advertising

  2. William Ahern

    Ben Pfaff Guest

    Finally, a really interesting question. I see so few questions I
    want to answer these days. Either the quality of the questions
    is declining or my pickiness is increasing. Probably the latter.

    William Ahern <william@wilbur.25thandClement.com> writes:

    > Here's the supposedly offending code (no laughing or grimacing, please ;)
    >
    > char *s, *s1;
    >
    > s1 = strcpy((char [strlen(s) + 1]){ },s);
    >
    > and GCC 4.01's error messages
    >
    > error: compound literal has variable size
    > error: empty scalar initializer
    > error: (near initialization for `(anonymous)')
    > First, is it really illegal to define a variable size for the compound array
    > literal? Do compound literals and VLA's not mix? If I store the array length
    > in a variable I get the same error.


    Here's your relevant C99 quote:

    6.5.2.5 Compound literals

    Constraints

    1 The type name shall specify an object type or an array of
    unknown size, but not a variable length array type.

    Go on and ask a hard one :)

    > Second, what is up with "empty scalar initializer"? If I add an explicit
    > zero--{ 0 }--the error obviously goes away. Does the "as if zero" rule not
    > apply if no initializers are given?


    A compound literal has this syntax:

    ( type-name ) { initializer-list }

    with the important sub-definitions being these:

    initializer-list:
    designation_opt initializer
    initializer-list , designation_opt initializer

    initializer:
    assignment-expression
    { initializer-list }
    { initializer-list , }

    In other words, the braces are not allowed to be empty. { ... }
    contains an initializer-list, an initializer-list contains at
    least one initializer, which contains an expression (or a
    sub-initializer-list), and an expression cannot be empty[*].

    [*] An expression *statement* can be empty but that's because of
    the syntax of expression-statement, not of the syntax of an
    expression.
    --
    "...deficient support can be a virtue.
    It keeps the amateurs off."
    --Bjarne Stroustrup
     
    Ben Pfaff, Aug 24, 2005
    #2
    1. Advertising

  3. William Ahern wrote:
    > So, GCC 4.01 is giving errors that GCC 3.3 did not, and I'm thinking they've
    > gone overboard with their new type checking infrastructure.
    >
    > Here's the supposedly offending code (no laughing or grimacing, please ;)
    >
    > char *s, *s1;
    >
    > s1 = strcpy((char [strlen(s) + 1]){ },s);
    >
    > and GCC 4.01's error messages
    >
    > error: compound literal has variable size
    > error: empty scalar initializer
    > error: (near initialization for `(anonymous)')
    >
    > First, is it really illegal to define a variable size for the compound array
    > literal? Do compound literals and VLA's not mix? If I store the array length
    > in a variable I get the same error.


    You cannot create a compound literal with variable length array type,
    attempting to do so is a constraint violation (6.5.2.5p1) and it's a
    good thing that gcc finally produces a diagnostic for this.

    > Second, what is up with "empty scalar initializer"? If I add an explicit
    > zero--{ 0 }--the error obviously goes away. Does the "as if zero" rule not
    > apply if no initializers are given?


    I have never heard of the "as if zero rule" but no, this is not
    allowed. You can't have an empty initializer list for any array type
    (i.e. int i[5] = {}; is not legal), what would make you think you can
    do so here?

    Robert Gamble
     
    Robert Gamble, Aug 24, 2005
    #3
  4. Robert Gamble <> wrote:
    > > Second, what is up with "empty scalar initializer"? If I add an explicit
    > > zero--{ 0 }--the error obviously goes away. Does the "as if zero" rule not
    > > apply if no initializers are given?


    > I have never heard of the "as if zero rule" but no, this is not
    > allowed. You can't have an empty initializer list for any array type
    > (i.e. int i[5] = {}; is not legal), what would make you think you can
    > do so here?


    Given
    struct {
    int a;
    int b;
    } x = {
    .b = 0,
    };

    then x.a is initialized "as-if" the initializer literally had ".a = 0". IOW,
    all unnamed members are initialized "as-if" set to zero.

    In C99, along with named initializers for structures, you can also
    initialize specified indices of arrays

    const char map[10] = { .[3] = '\n', };

    All the other indices are initialized to zero.

    I suppose my understanding of this behavior and nomenclature was
    insufficiently exact, thus my confusion.
     
    William Ahern, Aug 24, 2005
    #4
  5. Ben Pfaff <> wrote:
    > Finally, a really interesting question. I see so few questions I
    > want to answer these days. Either the quality of the questions
    > is declining or my pickiness is increasing. Probably the latter.
    >


    Thanks for coming out of the woodword, and for the very helpful answer. I'm
    ashamed to say I have a hard copy of the C99 standard on my desk. I thought
    I had tried to find the relevant section(s) last week. Either my memory is
    failing me or I'm becoming too lazy... or both. (That, and I still
    haven't develop a knack for finding stuff in the darn thing.)
     
    William Ahern, Aug 24, 2005
    #5
  6. William Ahern

    Ben Pfaff Guest

    William Ahern <william@wilbur.25thandClement.com> writes:

    > I'm ashamed to say I have a hard copy of the C99 standard on my
    > desk. I thought I had tried to find the relevant section(s)
    > last week. Either my memory is failing me or I'm becoming too
    > lazy... or both. (That, and I still haven't develop a knack for
    > finding stuff in the darn thing.)


    In my opinion: don't bother trying to find anything in the hard
    copy. Unless you already know where to look, you probably won't
    find what you're looking for. Instead, do full text search on
    the PDF version or, as I do, convert the PDF version to plain
    text and search that.
    --
    "A lesson for us all: Even in trivia there are traps."
    --Eric Sosman
     
    Ben Pfaff, Aug 24, 2005
    #6
  7. William Ahern wrote:
    > Robert Gamble <> wrote:
    > > > Second, what is up with "empty scalar initializer"? If I add an explicit
    > > > zero--{ 0 }--the error obviously goes away. Does the "as if zero" rule not
    > > > apply if no initializers are given?

    >
    > > I have never heard of the "as if zero rule" but no, this is not
    > > allowed. You can't have an empty initializer list for any array type
    > > (i.e. int i[5] = {}; is not legal), what would make you think you can
    > > do so here?

    >
    > Given
    > struct {
    > int a;
    > int b;
    > } x = {
    > .b = 0,
    > };
    >
    > then x.a is initialized "as-if" the initializer literally had ".a = 0". IOW,
    > all unnamed members are initialized "as-if" set to zero.
    >
    > In C99, along with named initializers for structures, you can also
    > initialize specified indices of arrays
    >
    > const char map[10] = { .[3] = '\n', };


    That should actually be:

    const char map[10] = { [3] = '\n' };

    the dot syntax is for structures, the bracket syntax is for arrays, and
    the trailing comma, although allowed (see the syntax Ben provided in
    his excellent response), is not required.

    > All the other indices are initialized to zero.
    >
    > I suppose my understanding of this behavior and nomenclature was
    > insufficiently exact, thus my confusion.


    Yes, members of arrays and structures not explicitly initialized in an
    initializer list are implicitly initialized following the same rules as
    objects with static duration (arithmetic types to 0, pointers to null).
    I had never heard of this referred to as the "as if zero" which was
    the cause for my confusion.

    Robert Gamble
     
    Robert Gamble, Aug 24, 2005
    #7
    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. John Goche
    Replies:
    8
    Views:
    16,466
  2. Mantorok Redgormor

    compound literals

    Mantorok Redgormor, Sep 14, 2003, in forum: C Programming
    Replies:
    3
    Views:
    405
    Mantorok Redgormor
    Sep 16, 2003
  3. Man with Oscilloscope

    VLA and goto -- diagnostic required?

    Man with Oscilloscope, Aug 24, 2006, in forum: C Programming
    Replies:
    8
    Views:
    384
    Christopher Benson-Manica
    Aug 30, 2006
  4. Marcus Harnisch

    Compound literals efficiency

    Marcus Harnisch, Jan 5, 2009, in forum: C Programming
    Replies:
    10
    Views:
    590
    Marcus Harnisch
    Jan 12, 2009
  5. kid joe

    Compound literals (anonymous aggregates)

    kid joe, Apr 21, 2009, in forum: C Programming
    Replies:
    21
    Views:
    1,126
    Richard Bos
    Apr 25, 2009
Loading...

Share This Page