Mixed initializer for char arrays?

J

James Kuyper

However, I'd like to initialize the array so that its first element is
defined with a (constant) integer expression,
char baz[4] = "\003baz";

I see only a string literal, no integer expression.

\003 is a constant integer expression.

If it occurred outside of a string literal or a character constant, and
the \ were removed, it would be an octal constant. If it were inside
single quotes, the whole thing would be a character constant - either
way, you'd be right. However, in it's actual context, it's just an octal
escape sequence, which is not a constant integer expression (though it
does specify an integer value to be stored in a character object).
 
T

Tim Rentsch

Eric Sosman said:
However, I'd like to initialize the array so that its first element is
defined with a (constant) integer expression,
char baz[4] = "\003baz";

I see only a string literal, no integer expression.

The initializer is to be produced by a macro. The integer expression
involves sizeof, so the above approach doesn't work.

Works for all the examples in your original post, though.
Maybe if you'd explain what you're trying to do, and why...
Or is it more fun to change the rules after each response? ;-)

Obviously what was meant, and was meant all along, is to use
an (arbitrary) integer constant expression for the first
element value.

Not understanding that in the first posting is perfectly
understandable. Not understanding it after the clarifying
response is just being obtuse.
 
T

Tim Rentsch

Barry Schwarz said:
However, I'd like to initialize the array so that its first element is
defined with a (constant) integer expression,
char baz[4] = "\003baz";

I see only a string literal, no integer expression.

\003 is a constant integer expression.
The initializer is to be produced by a macro. The integer expression
involves sizeof, so the above approach doesn't work.

Well, except that I can do:

#define FOO(n,s) \
(n == 0 ? "\0" s : n == 1 ? "\1" s : n == 2 ? "\2" s : ....)

If the character following the integer could be a digit, you need to
expand these to three octal characters. But the preprocessor will not
evaluate the ?: operator so you could not use this in an attempt to
concatenate an integer to a string as part of an initializer.

I'm not sure what you mean by "But the preprocssor will not
evaluate the ?: operator..." sentence. Are you trying to say
this expression cannot be used to initialize a file scope
declaration? It can. Assuming a call like

FOO( sizeof "whatever" - 1, "whatever" )

the expansion qualifies under 6.6p7 as a constant expression and
may be used as an initializing expression for variables of static
storage duration.
 
S

Shao Miller

However, I'd like to initialize the array so that its first element is
defined with a (constant) integer expression,

char baz[4] = "\003baz";

I see only a string literal, no integer expression.

\003 is a constant integer expression.
The initializer is to be produced by a macro. The integer expression
involves sizeof, so the above approach doesn't work.

Well, except that I can do:

#define FOO(n,s) \
(n == 0 ? "\0" s : n == 1 ? "\1" s : n == 2 ? "\2" s : ....)

If the character following the integer could be a digit, you need to
expand these to three octal characters. But the preprocessor will not
evaluate the ?: operator so you could not use this in an attempt to
concatenate an integer to a string as part of an initializer.

I'm not sure what you mean by "But the preprocssor will not
evaluate the ?: operator..." sentence. Are you trying to say
this expression cannot be used to initialize a file scope
declaration? It can. Assuming a call like

FOO( sizeof "whatever" - 1, "whatever" )

the expansion qualifies under 6.6p7 as a constant expression and
may be used as an initializing expression for variables of static
storage duration.

My impression was that he meant that the macro wouldn't expand to a
string literal suitable for automatic concatenation beside some other
string literal. As in:

FOO(...) "suffix"

to:

"prefix" "suffix"
 
B

Barry Schwarz

Barry Schwarz said:
However, I'd like to initialize the array so that its first element is
defined with a (constant) integer expression,

char baz[4] = "\003baz";

I see only a string literal, no integer expression.

\003 is a constant integer expression.
The initializer is to be produced by a macro. The integer expression
involves sizeof, so the above approach doesn't work.

Well, except that I can do:

#define FOO(n,s) \
(n == 0 ? "\0" s : n == 1 ? "\1" s : n == 2 ? "\2" s : ....)

If the character following the integer could be a digit, you need to
expand these to three octal characters. But the preprocessor will not
evaluate the ?: operator so you could not use this in an attempt to
concatenate an integer to a string as part of an initializer.

I'm not sure what you mean by "But the preprocssor will not
evaluate the ?: operator..." sentence. Are you trying to say
this expression cannot be used to initialize a file scope
declaration? It can. Assuming a call like

FOO( sizeof "whatever" - 1, "whatever" )

the expansion qualifies under 6.6p7 as a constant expression and
may be used as an initializing expression for variables of static
storage duration.

Are you saying that

static char baz[4] = {(1 == 0 ? "\0" : 1 == 1 ? "\1" : "\2")"baz"};

which is what the compiler sees after macro substitution, is valid?
For what it's worth, my compiler doesn't accept it. It does accept it
without the parentheses but only initializes the first byte. The
remaining 3 are set to '\0'.

Changing the two left operands of the == operators to 5 did produce
the "desired" initialization ("\2baz"). This leads to the conclusion
that the two strings must be physically adjacent in the source and any
intervening text, even if not evaluated, messes up the string literal
concatenation process.

And with respect to 6.6p7, doesn't the result of the evaluation have
to be an arithmetic constant, and address constant, or a null pointer
constant? I don't see any arithmetic constants or null pointer
constants. And in the case of initialization, the implicit array type
of the string literal does not undergo the normal conversion to the
address of the first array element so there are no address constants
either.
 
L

Lauri Alanko

If the character following the integer could be a digit, you need to
expand these to three octal characters.

I'm not sure about that. The standard says (6.4.5):

"the multibyte character sequences specified by any sequence of
adjacent character and wide string literal tokens are concatenated
into a single multibyte character sequence"

Note that the character sequences _specified_ by the string literals
are concatenated, not the text of the string literals themselves. I
read this as meaning that the escape sequences are interpreted before
concatenation. This is also the behavior of gcc and clang.
But the preprocessor will not
evaluate the ?: operator so you could not use this in an attempt to
concatenate an integer to a string as part of an initializer.

You seem to have been consistently misreading the above macro. It's
true that it doesn't work as an array initializer but it does work as
a char* initializer:

#define FOO(n, s) \
(n == 0 ? "\0" s : n == 1 ? "\1" s : n == 2 ? "\2" s : 0)

const char* foo = FOO(sizeof("x") - 1, "x");

Do note that FOO has _two_ arguments. :)


Lauri
 
T

Tim Rentsch

Barry Schwarz said:
Barry Schwarz said:
However, I'd like to initialize the array so that its first element is
defined with a (constant) integer expression,

char baz[4] = "\003baz";

I see only a string literal, no integer expression.

\003 is a constant integer expression.


The initializer is to be produced by a macro. The integer expression
involves sizeof, so the above approach doesn't work.

Well, except that I can do:

#define FOO(n,s) \
(n == 0 ? "\0" s : n == 1 ? "\1" s : n == 2 ? "\2" s : ....)

If the character following the integer could be a digit, you need to
expand these to three octal characters. But the preprocessor will not
evaluate the ?: operator so you could not use this in an attempt to
concatenate an integer to a string as part of an initializer.

I'm not sure what you mean by "But the preprocssor will not
evaluate the ?: operator..." sentence. Are you trying to say
this expression cannot be used to initialize a file scope
declaration? It can. Assuming a call like

FOO( sizeof "whatever" - 1, "whatever" )

the expansion qualifies under 6.6p7 as a constant expression and
may be used as an initializing expression for variables of static
storage duration.

Are you saying that

static char baz[4] = {(1 == 0 ? "\0" : 1 == 1 ? "\1" : "\2")"baz"};

which is what the compiler sees after macro substitution, is valid?
[snip elaboration]

I'm not. If you look again at the actual #define FOO, and
the example call I gave, I expect you will see that I'm
not.
 
T

Tim Rentsch

Shao Miller said:
However, I'd like to initialize the array so that its first element is
defined with a (constant) integer expression,

char baz[4] = "\003baz";

I see only a string literal, no integer expression.

\003 is a constant integer expression.


The initializer is to be produced by a macro. The integer expression
involves sizeof, so the above approach doesn't work.

Well, except that I can do:

#define FOO(n,s) \
(n == 0 ? "\0" s : n == 1 ? "\1" s : n == 2 ? "\2" s : ....)

If the character following the integer could be a digit, you need to
expand these to three octal characters. But the preprocessor will not
evaluate the ?: operator so you could not use this in an attempt to
concatenate an integer to a string as part of an initializer.

I'm not sure what you mean by "But the preprocssor will not
evaluate the ?: operator..." sentence. Are you trying to say
this expression cannot be used to initialize a file scope
declaration? It can. Assuming a call like

FOO( sizeof "whatever" - 1, "whatever" )

the expansion qualifies under 6.6p7 as a constant expression and
may be used as an initializing expression for variables of static
storage duration.

My impression was that he meant that the macro wouldn't expand to a
string literal suitable for automatic concatenation beside some other
string literal. As in:

FOO(...) "suffix"

to:

"prefix" "suffix"

Yes, it looks like you're right. I try to figure
out what it is people really mean when what they
say doesn't make sense, but I didn't get this one.
 

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,777
Messages
2,569,604
Members
45,226
Latest member
KristanTal

Latest Threads

Top