if else块里面的字符串赋值?

时间:2014-10-20 10:16:39

标签: c undefined-behavior

这是未定义的行为吗? (因为字符串“True”,“False”和“Error”仅在块内退出并在退出块时被销毁):

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

我认为这同样适用于switch语句。那么我怎么能表达上面的逻辑呢?

子问题: 这也是未定义的行为吗? :

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

6 个答案:

答案 0 :(得分:5)

没有任何未定义的行为。字符串文字具有静态存储持续时间。 只有无效代码(在编辑帖子之前),因为您忘记在语句中指定条件

else if

根据C标准(6.4.5字符串文字)

  

6在转换阶段7中,附加一个值为零的字节或代码   每个由字符串文字产生的多字节字符序列   或者文字.78)然后使用多字节字符序列   初始化一个静态存储持续时间和长度的数组   足以包含序列

至于复合文字,那么代码片段确实有未定义的行为。根据C标准(6.5.2.5复合文字)

  

5复合文字的值是未命名对象的值   由初始化列表初始化。如果出现复合文字   在函数体外,该对象具有静态存储   持续时间; 否则,它具有相关的自动存储持续时间   封闭区块

考虑到必须有

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

如果您要编写

,代码段将是有效的
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);

答案 1 :(得分:1)

至于此代码段'关注,没有问题。 (从代码中删除了无用/不完整的if else检查:-))

int main ()
{
  char *p;
  int var = 0;

  if (var){
    p = "True";
  } else {
    p = "False";
  }

  printf("%s\n", p);
  return 0;
}

如果var = 0,它将打印" False"否则它将打印" True"。

答案 2 :(得分:1)

字符串文字具有静态存储持续时间。

  

6.4.5。 p6在转换阶段7中,将值为零的字节或代码附加到每个多字节   由字符串文字或文字产生的字符序列.78)多字节字符   然后,序列用于初始化静态存储持续时间和长度的数组   足以包含序列。

静态存储持续时间意味着变量在程序启动时初始化,并在整个程序中有效。

您的第一个示例没有未定义的行为。

但是在第二个示例中,您尝试指向具有自动存储持续时间的复合文字,这意味着一旦退出if语句,它们就不再存在。

  

6.5.2.5。 p5复合文字的值是由初始化的未命名对象的值   初始化列表。如果复合文字出现在函数体外,则为对象   有静态存储时间;否则,它与自动存储持续时间相关联   封闭的块。

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

barptr->i = 123 ;   //UNDEFINED BEHAVIOR

答案 3 :(得分:0)

通常,字符串文字(“True”和“False”)将存储在数据部分的只读页面中

所以它不是未定义的行为。

答案 4 :(得分:0)

这是明确的定义。按标准:

  

6.4.5字符串文字

     

语法

[...]

  

描述

     

2字符串文字是包含在其中的零个或多个多字节字符的序列   双引号,如“xyz”。宽字符串文字是相同的,除了前缀   信L。

所以你的作业是stringliterals。关于Stringliterals的使用寿命ISO / IEC 9899:TC3说:

[...]

  

5在转换阶段7中,将值为零的字节或代码附加到每个多字节   由字符串文字或文字产生的字符序列。多字节字符   然后,序列用于初始化静态存储持续时间和长度的数组   足以包含序列。

因此,您可以看到从程序的开始到终止存在字符串文字。

现在你也知道他们就是这样的“字符串文字”

所以你可以肯定。

绝对定义明确。

答案 5 :(得分:-2)

  

这是未定义的行为吗? (因为字符串“True”,“False”和“Error”仅在块内退出并在块退出时被销毁)

没有。你应该看看变量,而不是文字。在char* p中调用时,printf存在。