Puzzling compiler response to array initialization.

M

Michael Press

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

pete

Michael said:
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.
 
P

pete

pete said:
Michael said:
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'};
 
A

A. Sinan Unur

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
 
P

pete

A. Sinan Unur said:
#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 */
 
M

Michael Press

pete said:
Michael said:
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.

?
 
M

Michael Press

"A. Sinan Unur said:
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.
 
P

pete

Michael said:
pete said:
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.
 
P

pete

pete said:
Michael said:
pete said:
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.
 
F

Flash Gordon

Michael said:
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.
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.
 
P

pete

pete said:
Michael said:
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.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.
 
M

Michael Press

pete said:
pete said:
Michael Press 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?
 
P

pete

Michael said:
pete said:
pete said:
pete wrote:

Michael Press 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.";
 
K

Keith Thompson

pete said:
Michael said:
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.
 
M

Michael Wojcik

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 (e-mail address removed)

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top