Puzzling compiler response to array initialization.

Discussion in 'C Programming' started by Michael Press, Oct 4, 2005.

  1. Hello. I am puzzled. A line of the form

    char array[] = { a};

    or

    char array[] = { a, b, c};

    is an array initializer.

    _Except_

    102$ cat try.c
    #include <stdio.h>

    int main ()
    {
    char ao[] = { "Hello" };
    char at[] = { "Hello", "Goodbye." };

    return 0;
    } /* main */

    103$ cc -W try.c
    try.c: In function `main':
    try.c:6: excess elements in char array initializer
    try.c:6: (near initialization for `at')

    Line 5 passes, but it should get the same error as line 6.

    --
    Michael Press
     
    Michael Press, Oct 4, 2005
    #1
    1. Advertising

  2. Michael Press

    pete Guest

    Michael Press wrote:
    >
    > Hello. I am puzzled. A line of the form
    >
    > char array[] = { a};
    >
    > or
    >
    > char array[] = { a, b, c};
    >
    > is an array initializer.
    >
    > _Except_
    >
    > 102$ cat try.c
    > #include <stdio.h>
    >
    > int main ()
    > {
    > char ao[] = { "Hello" };
    > char at[] = { "Hello", "Goodbye." };


    char *at[] = { "Hello", "Goodbye." };

    >
    > return 0;
    > } /* main */
    >
    > 103$ cc -W try.c
    > try.c: In function `main':
    > try.c:6: excess elements in char array initializer
    > try.c:6: (near initialization for `at')
    >
    > Line 5 passes, but it should get the same error as line 6.


    There's nothing wrong with line 5.

    char ao[] = { "Hello" };
    is shorthand for:
    char ao[] = { 'H','e','l','l','o','\n'};

    { "Hello", "Goodbye." } is an initializer for an array of pointers.

    --
    pete
     
    pete, Oct 4, 2005
    #2
    1. Advertising

  3. Michael Press

    pete Guest

    pete wrote:
    >
    > Michael Press wrote:
    > >
    > > Hello. I am puzzled. A line of the form
    > >
    > > char array[] = { a};
    > >
    > > or
    > >
    > > char array[] = { a, b, c};
    > >
    > > is an array initializer.
    > >
    > > _Except_
    > >
    > > 102$ cat try.c
    > > #include <stdio.h>
    > >
    > > int main ()
    > > {
    > > char ao[] = { "Hello" };
    > > char at[] = { "Hello", "Goodbye." };

    >
    > char *at[] = { "Hello", "Goodbye." };
    >
    > >
    > > return 0;
    > > } /* main */
    > >
    > > 103$ cc -W try.c
    > > try.c: In function `main':
    > > try.c:6: excess elements in char array initializer
    > > try.c:6: (near initialization for `at')
    > >
    > > Line 5 passes, but it should get the same error as line 6.

    >
    > There's nothing wrong with line 5.
    >
    > char ao[] = { "Hello" };
    > is shorthand for:
    > char ao[] = { 'H','e','l','l','o','\n'};


    Excuse me. I meant

    char ao[] = { 'H','e','l','l','o','\0'};


    --
    pete
     
    pete, Oct 4, 2005
    #3
  4. Michael Press <> wrote in news:jack-B9EA52.19181703102005
    @newsclstr02.news.prodigy.com:

    > Hello. I am puzzled. A line of the form
    >
    > char array[] = { a};


    Well, no. Either

    char array[] = { 'a' };

    or,

    char array[] = "a";

    > char array[] = { a, b, c};


    Similarly:

    char array[] = { 'a', 'b', 'c', };

    > 102$ cat try.c
    > #include <stdio.h>
    >
    > int main ()
    > {
    > char ao[] = { "Hello" };


    The RHS is an array of char *.

    So,

    char *ao[] = { "Hello" };

    > char at[] = { "Hello", "Goodbye." };


    char *at[] = { "Hello", "Goodbye.", };

    /* --- */
    #include <stdio.h>

    int main () {
    size_t i;
    char ac[] = { 'H', 'e', 'l', 'l', 'o', };
    char *at[] = { "Hello", "Goodbye.", "etc" };
    for (i = 0; i != sizeof(at)/sizeof(at[0]); ++i) {
    puts(at);
    }
    for (i = 0; i != sizeof(ac); ++i) {
    printf("%c\n", ac);
    }
    return 0;
    }
    /* --- */

    Sinan

    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
     
    A. Sinan Unur, Oct 4, 2005
    #4
  5. pete <> wrote:

    > char ao[] = { "Hello" };
    > is shorthand for:
    > char ao[] = { 'H','e','l','l','o','\n'};

    ^^^^
    ITYM '\0', presumably?

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Oct 4, 2005
    #5
  6. Michael Press

    pete Guest

    A. Sinan Unur wrote:
    >
    > Michael Press <> wrote in news:jack-B9EA52.19181703102005


    > > #include <stdio.h>
    > >
    > > int main ()
    > > {
    > > char ao[] = { "Hello" };

    >
    > The RHS is an array of char *.


    It can be, but it isn't.

    /* BEGIN new.c */

    #include <stdio.h>

    int main(void)
    {
    char ao[] = { "Hello" };
    char *at[] = { "World" };

    puts(ao );
    puts(at[0]);
    return 0;
    }

    /* END new.c */

    --
    pete
     
    pete, Oct 4, 2005
    #6
  7. Michael Press

    pete Guest

    Christopher Benson-Manica wrote:
    >
    > pete <> wrote:
    >
    > > char ao[] = { "Hello" };
    > > is shorthand for:
    > > char ao[] = { 'H','e','l','l','o','\n'};

    > ^^^^
    > ITYM '\0', presumably?


    Yes.

    --
    pete
     
    pete, Oct 4, 2005
    #7
  8. pete <> wrote in news::

    > A. Sinan Unur wrote:
    >>
    >> Michael Press <> wrote in news:jack-B9EA52.19181703102005

    >
    >> > #include <stdio.h>
    >> >
    >> > int main ()
    >> > {
    >> > char ao[] = { "Hello" };

    >>
    >> The RHS is an array of char *.

    >
    > It can be, but it isn't.
    >


    Yes. I had meant to put that comment further below. Sorry about that.

    Sinan

    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)
     
    A. Sinan Unur, Oct 4, 2005
    #8
  9. pete <> wrote:

    > Yes.


    I saw your correction after I posted mine. My apologies.

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Oct 4, 2005
    #9
  10. In article <>,
    pete <> wrote:

    > Michael Press wrote:
    > >
    > > Hello. I am puzzled. A line of the form
    > >
    > > char array[] = { a};
    > >
    > > or
    > >
    > > char array[] = { a, b, c};
    > >
    > > is an array initializer.
    > >
    > > _Except_
    > >
    > > 102$ cat try.c
    > > #include <stdio.h>
    > >
    > > int main ()
    > > {
    > > char ao[] = { "Hello" };
    > > char at[] = { "Hello", "Goodbye." };

    >
    > char *at[] = { "Hello", "Goodbye." };
    >
    > >
    > > return 0;
    > > } /* main */
    > >
    > > 103$ cc -W try.c
    > > try.c: In function `main':
    > > try.c:6: excess elements in char array initializer
    > > try.c:6: (near initialization for `at')
    > >
    > > Line 5 passes, but it should get the same error as line 6.

    >
    > There's nothing wrong with line 5.
    >
    > char ao[] = { "Hello" };
    > is shorthand for:
    > char ao[] = { 'H','e','l','l','o','\n'};


    Where does the standard say this?

    "Hello"

    evaluates to a pointer to char.

    > { "Hello", "Goodbye." } is an initializer for an array of pointers.


    Yes, I know this.

    I assert that there is something wrong with line 5. An
    item in an initializer-list to an array of char should
    evaluate to a char, and "Hello" does not evaluate to a
    char.

    I do not have at hand a Backus-Naur grammar for C; only
    K&R 1st edition, and it does not allow the initializer

    char ao[] = { "Hello" };

    Can anyone point me at an up to date Backus-Naur grammar
    for C?

    To be more plain

    char at[] = { "Hello", "Goodbye." };

    is manifestly incorrect, but

    char ao[] = { "Hello" };

    is incorrrect by the same reasoning.

    ?

    --
    Michael Press
     
    Michael Press, Oct 4, 2005
    #10
  11. In article <Xns96E4E63DD3196asu1cornelledu@127.0.0.1>,
    "A. Sinan Unur" <> wrote:

    > Michael Press <> wrote in news:jack-B9EA52.19181703102005
    > @newsclstr02.news.prodigy.com:
    >
    > > Hello. I am puzzled. A line of the form
    > >
    > > char array[] = { a};

    >
    > Well, no. Either
    >
    > char array[] = { 'a' };
    >
    > or,
    >
    > char array[] = "a";
    >
    > > char array[] = { a, b, c};

    >
    > Similarly:
    >
    > char array[] = { 'a', 'b', 'c', };


    I did not specify a; simply meant it to be valid for an
    initilializer. For instance

    char a = (char) 'a';
    char array[] = {a};

    I apologize for confusing the matter.

    --
    Michael Press
     
    Michael Press, Oct 4, 2005
    #11
  12. Michael Press

    pete Guest

    Michael Press wrote:
    >
    > In article <>,
    > pete <> wrote:
    >
    > > Michael Press wrote:


    > > char ao[] = { "Hello" };
    > > is shorthand for:
    > > char ao[] = { 'H','e','l','l','o','\n'};

    >
    > Where does the standard say this?



    N869
    6.3.2 Other operands
    6.3.2.1 Lvalues and function designators

    [#3] Except when it is the operand of the sizeof operator or
    the unary & operator, or is a string literal used to
    initialize an array, an expression that has type ``array of
    type'' is converted to an expression with type ``pointer to
    type'' that points to the initial element of the array
    object and is not an lvalue.

    --
    pete
     
    pete, Oct 4, 2005
    #12
  13. Michael Press

    pete Guest

    pete wrote:
    >
    > Michael Press wrote:
    > >
    > > In article <>,
    > > pete <> wrote:
    > >
    > > > Michael Press wrote:

    >
    > > > char ao[] = { "Hello" };
    > > > is shorthand for:
    > > > char ao[] = { 'H','e','l','l','o','\n'};


    That's supposed to end with a '\0' instead of a '\n'

    N869
    6.4.5 String literals

    [#5] In translation phase 7, a byte or code of value zero is
    appended to each multibyte character sequence that results
    from a string literal or literals. The multibyte
    character sequence is then used to initialize an array of
    static storage duration and length just sufficient to
    contain the sequence.

    > > Where does the standard say this?

    >
    > N869
    > 6.3.2 Other operands
    > 6.3.2.1 Lvalues and function designators
    >
    > [#3] Except when it is the operand of the sizeof operator or
    > the unary & operator, or is a string literal used to
    > initialize an array, an expression that has type ``array of
    > type'' is converted to an expression with type ``pointer to
    > type'' that points to the initial element of the array
    > object and is not an lvalue.


    --
    pete
     
    pete, Oct 4, 2005
    #13
  14. Michael Press

    Flash Gordon Guest

    Michael Press wrote:
    > In article <>,
    > pete <> wrote:


    <snip>

    >> char ao[] = { "Hello" };
    >>is shorthand for:
    >> char ao[] = { 'H','e','l','l','o','\n'};

    >
    >
    > Where does the standard say this?
    >
    > "Hello"
    >
    > evaluates to a pointer to char.


    Not when used to initialise an array of char it doesn't.

    >>{ "Hello", "Goodbye." } is an initializer for an array of pointers.

    >
    >
    > Yes, I know this.
    >
    > I assert that there is something wrong with line 5. An
    > item in an initializer-list to an array of char should
    > evaluate to a char, and "Hello" does not evaluate to a
    > char.


    You are wrong.

    > I do not have at hand a Backus-Naur grammar for C; only
    > K&R 1st edition, and it does not allow the initializer
    >
    > char ao[] = { "Hello" };


    K&R1 is hopelessly out of date. There were a number of important changes
    in the language after it was released so you should get a copy of K&R2
    which has been out for over 15 years.

    > Can anyone point me at an up to date Backus-Naur grammar
    > for C?


    I can't, but there are several draft versions of the standard available
    legally for free on the net, I'm using n1124.pdf at the moment.

    > To be more plain
    >
    > char at[] = { "Hello", "Goodbye." };
    >
    > is manifestly incorrect, but
    >
    > char ao[] = { "Hello" };
    >
    > is incorrrect by the same reasoning.
    >
    > ?


    In N1124 section 6.8.7 Initialization there is the following text:
    | 14 An array of character type may be initialized by a character string
    | literal, optionally enclosed in braces. Successive characters of
    | the character string literal (including the terminating null
    | character if there is room or if the array is of unknown size)
    | initialize the elements of the array.

    I believe this has been the case since at least the original ANSI
    standard published in 1989, although the wording may have change.
    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
     
    Flash Gordon, Oct 4, 2005
    #14
  15. Michael Press

    pete Guest

    pete wrote:
    >
    > pete wrote:
    > >
    > > Michael Press wrote:
    > > >
    > > > In article <>,
    > > > pete <> wrote:
    > > >
    > > > > Michael Press wrote:

    > >
    > > > > char ao[] = { "Hello" };
    > > > > is shorthand for:
    > > > > char ao[] = { 'H','e','l','l','o','\n'};

    >
    > That's supposed to end with a '\0' instead of a '\n'


    > > > Where does the standard say this?

    > >
    > > N869
    > > 6.3.2 Other operands
    > > 6.3.2.1 Lvalues and function designators


    This is probably a better quote here:

    N869
    6.7.8 Initialization

    [#14] An array of character type may be initialized by a
    character string literal, optionally enclosed in braces.
    Successive characters of the character string literal
    (including the terminating null character if there is room
    or if the array is of unknown size) initialize the elements
    of the array.

    --
    pete
     
    pete, Oct 4, 2005
    #15
  16. In article <>,
    pete <> wrote:

    > pete wrote:
    > >
    > > pete wrote:
    > > >
    > > > Michael Press wrote:
    > > > >
    > > > > In article <>,
    > > > > pete <> wrote:
    > > > >
    > > > > > Michael Press wrote:
    > > >
    > > > > > char ao[] = { "Hello" };
    > > > > > is shorthand for:
    > > > > > char ao[] = { 'H','e','l','l','o','\n'};

    > >
    > > That's supposed to end with a '\0' instead of a '\n'

    >
    > > > > Where does the standard say this?
    > > >
    > > > N869
    > > > 6.3.2 Other operands
    > > > 6.3.2.1 Lvalues and function designators

    >
    > This is probably a better quote here:
    >
    > N869
    > 6.7.8 Initialization
    >
    > [#14] An array of character type may be initialized by a
    > character string literal, optionally enclosed in braces.
    > Successive characters of the character string literal
    > (including the terminating null character if there is room
    > or if the array is of unknown size) initialize the elements
    > of the array.


    Thank you.

    Next question. Why did the standard make a special case of
    char a[] = {"Hello"}; ? If the special case did not exist
    the code would precipitate a compile time error. Who needs
    that construction?

    --
    Michael Press
     
    Michael Press, Oct 5, 2005
    #16
  17. Michael Press

    pete Guest

    Michael Press wrote:
    >
    > In article <>,
    > pete <> wrote:
    >
    > > pete wrote:
    > > >
    > > > pete wrote:
    > > > >
    > > > > Michael Press wrote:
    > > > > >
    > > > > > In article <>,
    > > > > > pete <> wrote:
    > > > > >
    > > > > > > Michael Press wrote:
    > > > >
    > > > > > > char ao[] = { "Hello" };
    > > > > > > is shorthand for:
    > > > > > > char ao[] = { 'H','e','l','l','o','\n'};
    > > >
    > > > That's supposed to end with a '\0' instead of a '\n'

    > >
    > > > > > Where does the standard say this?
    > > > >
    > > > > N869
    > > > > 6.3.2 Other operands
    > > > > 6.3.2.1 Lvalues and function designators

    > >
    > > This is probably a better quote here:
    > >
    > > N869
    > > 6.7.8 Initialization
    > >
    > > [#14] An array of character type may be initialized by a
    > > character string literal, optionally enclosed in braces.
    > > Successive characters of the character string literal
    > > (including the terminating null character if there is room
    > > or if the array is of unknown size) initialize the elements
    > > of the array.

    >
    > Thank you.
    >
    > Next question. Why did the standard make a special case of
    > char a[] = {"Hello"}; ? If the special case did not exist
    > the code would precipitate a compile time error. Who needs
    > that construction?


    Almost every initialization of an array of char
    with a string is done that way.

    Who wants to write { 'H','e','l','l','o','\0'}
    when they can just write "Hello"?
    As you can see, I couldn't even spell { 'H','e','l','l','o','\0' }
    correctly on my first attempt.

    char string[] = "... and when the string is longer, "
    "the other way is really tedious.";

    --
    pete
     
    pete, Oct 5, 2005
    #17
  18. pete <> writes:
    > Michael Press wrote:
    >> In article <>,
    >> pete <> wrote:

    [...]
    >> > N869
    >> > 6.7.8 Initialization
    >> >
    >> > [#14] An array of character type may be initialized by a
    >> > character string literal, optionally enclosed in braces.
    >> > Successive characters of the character string literal
    >> > (including the terminating null character if there is room
    >> > or if the array is of unknown size) initialize the elements
    >> > of the array.

    >>
    >> Thank you.
    >>
    >> Next question. Why did the standard make a special case of
    >> char a[] = {"Hello"}; ? If the special case did not exist
    >> the code would precipitate a compile time error. Who needs
    >> that construction?

    >
    > Almost every initialization of an array of char
    > with a string is done that way.
    >
    > Who wants to write { 'H','e','l','l','o','\0'}
    > when they can just write "Hello"?
    > As you can see, I couldn't even spell { 'H','e','l','l','o','\0' }
    > correctly on my first attempt.
    >
    > char string[] = "... and when the string is longer, "
    > "the other way is really tedious.";


    Well, of course. I think the question was why the standard allows
    char s[] = { "hello" };
    as well as
    char s[] = "hello";

    I suspect the point is that all initializations can be enclosed in
    braces, even
    int n = { 42 };

    I don't really see the point myself; perhaps someone who does can
    explain the rationale.

    --
    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.
     
    Keith Thompson, Oct 5, 2005
    #18
  19. In article <>, Keith Thompson <> writes:
    >
    > I suspect the point is that all initializations can be enclosed in
    > braces, even
    > int n = { 42 };
    >
    > I don't really see the point myself; perhaps someone who does can
    > explain the rationale.


    For one thing, it means {0} is a valid initializer for an object of
    any (complete, object) type.

    Possible considerations that come to mind: it simplifies generating
    source code programmatically; it allows for a certain consistency
    of style; it's similar to the rule permitting extraneous parentheses
    around expressions; and it doesn't hurt anything.

    --
    Michael Wojcik

    Thanks for your prompt reply and thanks for your invitatin to your
    paradise. Based on Buddihism transmigration, I realize you, European,
    might be a philanthropist in previous life! -- supplied by Stacy Vickers
     
    Michael Wojcik, Oct 5, 2005
    #19
    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. JKop
    Replies:
    10
    Views:
    990
  2. Matthias Kaeppler
    Replies:
    2
    Views:
    470
    Victor Bazarov
    Jul 18, 2005
  3. toton
    Replies:
    5
    Views:
    950
    Victor Bazarov
    Sep 28, 2006
  4. aaragon
    Replies:
    2
    Views:
    637
    James Kanze
    Nov 2, 2008
  5. A. S. Bradbury

    Puzzling bug with yielded array

    A. S. Bradbury, Sep 8, 2006, in forum: Ruby
    Replies:
    10
    Views:
    222
    Rick DeNatale
    Sep 10, 2006
Loading...

Share This Page