user10607
user10607

Reputation: 3071

String assignment inside if else block?

Is this undefined behaviour? (Because the strings "True", "False" and "Error" only exit within the blocks and are destroyed when a block is exited):

char *p;
if (var1) {
    p = "True";
} else if (var2) { 
    p = "False";
} else {
    p = "Error";
}
printf("%s\n", p);

The same applies for the switch statement I guess. Then how could I express the logic above?

Sub question: Is this also undefined behaviour? :

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);

Upvotes: 3

Views: 145

Answers (6)

2501
2501

Reputation: 25752

String literals have static storage duration.

6.4.5. p6 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.78)The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence.

Static storage duration means that variables are initialized at program startup and are valid throughout the program.

You first example does not have undefined behavior.

However in the second example you try to point to compound literals which have automatic storage duration, this means that once you exit the if statement they don't exists anymore.

6.5.2.5. p5 The value of the compound literal is that of an unnamed object initialized by the initializer list. If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.

struct bar *barptr;
if (var1){
    barptr = &(struct bar) { 0, 0.0 }; 
} else {
    barptr = &(struct bar) { 5, 40.3 };
}                                      

barptr->i = 123 ;   //UNDEFINED BEHAVIOR

Upvotes: 1

dhein
dhein

Reputation: 6555

This is well defined. As by 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". A wide string literal is the same, except prefixed by the letter L.

And so your assignments are stringliterals. And About Stringliterals life time the ISO/IEC 9899:TC3 says:

[...]

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.

So you can see a String literal exists from the starting up to the termination of your programm.

And now you also know they are such "string literals"

So you can be sure.

It is absolutly well defined.

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

Reputation: 310980

There is no any undefined behaviour. String literals have the static storage duration. There is only invalid code (that was before you edited your post) because you forgot to specify a condition in statement

else if

According to the C Standard (6.4.5 String literals)

6 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.78) The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence

As for the compound literals then the code snippet indeed has undefined behaviour. According to the C Standard (6.5.2.5 Compound literals)

5 The value of the compound literal is that of an unnamed object initialized by the initializer list. If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.

Take into account that there must be

barptr = &(struct bar) { 0, 0.0 };

The code snippet would be valid if you would 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);

Upvotes: 5

quez
quez

Reputation: 1

This is undefined behaviour right? (Because the strings "True", "False" and "Error" only exit within the blocks and are destroyed when a block is exited)

No. You should look on the variable, not on literals. Your char* p exists when you call it in printf.

Upvotes: -2

Jeegar Patel
Jeegar Patel

Reputation: 27210

Typically the string literal ("True" and "False") will be stored in the data section, in a read-only page

So its not undefined behaviour.

Upvotes: 0

Arjun Mathew Dan
Arjun Mathew Dan

Reputation: 5298

As far as 'this code snippet' is concerned, there is no issue. (Removed the useless/incomplete if else check from your code :-) )

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", else it will print "True".

Upvotes: 1

Related Questions