将字符数组 char u[10] 与字符串文字“abc”进行比较是否是未定义的行为

use*_*570 2 c++ pointers language-lawyer

我在 SO 上遇到了这个问题,以及这个问题的答案。代码如下:

int main()
{

    char u[10];
    cout<<"Enter shape name ";
    cin>>u;
    if(u=="tri") //IS THIS UNDEFINED BEHAVIOR because the two decayed pointers both point to unrelated objects?
    {
        cout<<"everything is fine";
    }
    else
    {
        cout<<"Not fine";
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我在提到的答案中读到,两者u"tri"衰减到指向其第一个元素的指针。我的问题是,现在比较这两个腐烂的指针是否是未定义的行为,因为这些指针指向不相关的对象?或者程序很好/有效(没有 UB)并且因为指针具有不同的值,所以 else 分支将被执行?

for*_*818 5

比较指针 via在compound#expr==中定义:

如果至少其中一个操作数是指针,则对这两个操作数执行指针转换、函数指针转换和限定转换,以将它们转换为复合指针类型。比较指针的定义如下:

(3.1) 如果一个指针代表一个完整对象的地址,而另一个指针代表另一个完整对象的最后一个元素之后的地址,则比较结果未指定。

(3.2) 否则,如果指针都为空,都指向同一个函数,或者都代表相同的地址,则它们比较相等。

(3.3) 否则,指针比较不相等。

您的示例中的两个指针都不代表[不同]完整对象的最后一个元素之后的地址。两个指针都不为空。它们不代表同一个地址。因此u=="tri"是假的。

比较指针 via<是另一回事,因为指针值之间需要有某种排序。通过它比较两个指针==只关心它们的值是否相同。


eer*_*ika 5

标准说:

[表达式.eq]

==(等于)和 !=(不等于)运算符从左到右分组。左值到右值 ([conv.lval])、数组到指针([conv.array]) 和函数到指针 ([conv.func]) 标准转换在操作数上执行...

因此,我们正在比较指向各自数组的指针。

如果至少一个操作数是指针,...比较指针定义如下:

  • 如果一个指针代表一个完整对象的地址,而另一个指针代表另一个完整对象的最后一个元素之后的地址,72 比较的结果是未指定的。[不适用,因为两个指针都没有超过最后一个元素]
  • 否则,如果指针都为空,都指向同一个函数,或者都表示相同的地址,则它们比较相等。[不适用,因为两者都不为空,既不指向函数,也不代表相同的地址]
  • 否则,指针比较不相等。[适用]

行为已定义,否则分支将无条件执行。

无条件无条件 if 语句意味着可能存在错误;最有可能的是作者试图比较数组的内容,而运算符不这样做。


“警告:与字符串文字比较会导致未指定的行为”

我认为这个警告消息有点误导。与两个字符串文字的比较将是未指定的:

if ("tri" == "tri")
Run Code Online (Sandbox Code Playgroud)

未指定该条件是真还是假。