String assignment inside if else block?
Is this behavior undefined? (Since the strings "True", "False" and "Error" only exit the blocks and are destroyed when the block exits):
char *p;
if (var1) {
p = "True";
} else if (var2) {
p = "False";
} else {
p = "Error";
}
printf("%s\n", p);
The same is true for the switch statement. Then how can I express the above logic?
Additional question: Is this also undefined behavior?
struct bar {
int i;
double d;
}
struct bar *barptr;
if (var1){
barptr = &(struct bar) { 0, 0.0 };
} else {
barptr = &(struct bar) { 5, 40.3 };
}
printf("%d", barptr->i);
source to share
There is no undefined behavior. String literals have static storage duration. There is only invalid code (which was before you edited your post) because you forgot to specify the condition in the expression
else if
According to the C standard (6.4.5 string literals)
6 In translation phase 7, a byte or code of zero value is appended to each multibyte character sequence that is derived from a string literal or literals. 78) The multibyte character sequence is then used to initialize an array of static storage duration , and the length is just long enough to contain the sequence
As far as compound literals are concerned, the code snippet does indeed have undefined behavior. According to the C standard (6.5.2.5. Component literals)
5 Composite literal value is the value of the name of an unnamed object initialized with an initializer list. If the compound literal is outside the function body, the object has static storage duration; otherwise it has an automatic storage duration with a closing unit .
Consider what should be
barptr = &(struct bar) { 0, 0.0 };
The code snippet will be valid if you write
struct bar {
int i;
double d;
};
struct bar bar;
if (var1){
bar = (struct bar) { 0, 0.0 };
} else {
bar = (struct bar) { 5, 40.3 };
}
printf("%d", bar.i);
source to share
As for "this piece of code", no problem. (Removed useless / incomplete if you check the code still :-))
int main ()
{
char *p;
int var = 0;
if (var){
p = "True";
} else {
p = "False";
}
printf("%s\n", p);
return 0;
}
if var = 0 it will print "False", otherwise it will print "True".
source to share
String literals have static storage duration.
6.4.5. p6 In phase 7 translation, a byte or code of zero value is appended to each multibyte with a character sequence that is obtained from a string literal or literals .78) The multibyte character sequence is used to initialize an array of static storage duration , and the length is just long enough to contain the sequence.
Static storage duration means that variables are initialized at program start and are valid throughout the program.
There is no undefined behavior in the first example.
However, in the second example, you are trying to point to compound literals that have automatic storage duration, which means that after the if statement exits, they no longer exist.
6.5.2.5. p5 The composite literal value is the name of an unnamed object initialized with an initializer list. If the compound literal occurs outside the body of a function, the object has a static storage duration; otherwise, it has an automatic retention time associated with the closing block.
struct bar *barptr;
if (var1){
barptr = &(struct bar) { 0, 0.0 };
} else {
barptr = &(struct bar) { 5, 40.3 };
}
barptr->i = 123 ; //UNDEFINED BEHAVIOR
source to share
This is well defined. As standard:
6.4.5 String literals
Syntax
[...]
Description
2 A character string literal is a sequence of zero or more multibyte characters, enclosed in double quotes, as in "xyz". The wide string literal is the same except the prefix letter L.
And so your assignments are stringliterals. And about the lifetime of Stringliterals in ISO / IEC 9899: TC3 says:
[...]
5 In phase 7 translation, a byte or code of zero value is added to each multibyte a sequence of characters that is obtained from a string literal or literals. The multibyte character sequence is used to initialize an array of static storage duration and length sufficient to contain the sequence.
So, you can see that the String literal exists from startup to completion of your program.
And now you also know that they are such "string literals"
So you can be sure.
Absolutely well defined.
source to share