2

为什么 c++ 编译器不抱怨以下代码?

#include<iostream>
int main()
{
    const char* p ="Hello";
    std::string q = p + 'H';
    std::cout << q << std::endl;
}

它正确地为以下代码抛出了错误

#include<iostream>
int main()
{
    const char* p ="Hello";
    std::string q = p + "World";
    std::cout << q << std::endl;
}

编译器抛出的错误语句

test.cxx: In function 'int main()':
test.cxx:5: error: invalid operands of types 'const char*' and 'const char [6]' to binary 'operator+'

有人可以帮助我理解,为什么第一个代码没有抛出任何错误语句?

4

5 回答 5

6

'H'是一个字符,一个整数类型。Sop + 'H'&p['H'](您基于 的数值进行索引'H')相同。第一个片段具有未定义的行为,因为 的数值'H'可能远大于 6,但编译器可以自由地不抱怨未定义的行为。

另一方面"World",它不是整数类型,也不能转换为整数类型。所以无法执行添加,点空白。

于 2017-10-31T08:17:24.683 回答
2

'H'单个字符,它的类型是char. Achar可以隐式转换为int,因此它将将此值添加到指针中p(按该值前进)。

请注意,它仍然是未定义的行为,因为新指针q指向数组之外。

于 2017-10-31T08:17:25.577 回答
2

两者都不执行字符串连接(如您所料)。

对于p + 'H',执行指针运算。'H'被视为带有 value 的整数72,然后p + 'H'将尝试返回指向数组第 73 个元素的指针,它越界"Hello"并导致UB,这意味着一切皆有可能;编译器不需要为它发出诊断。

对于p + "World",您要添加两个指针(即const char*),这根本没有意义。

我想你想做字符串连接,那么你应该使用std::string指针而不是指针std::string p ="Hello";,或者使用字符串文字(来自 C++14),例如std::string q = p + "World"s;,两者都会为你执行字符串连接。

于 2017-10-31T08:19:26.807 回答
2

在这份声明中

std::string q = p + "World";

字符串文字"World"被转换为指向其第一个字符的指针并具有类型const char *

所以尝试添加两个指针。这样的操作没有定义并且编译器发出错误。

在这份声明中

std::string q = p + 'H';

使用了添加整数值的有效操作'H'(由于对指针的积分提升而隐式转换为类型int。即在用作初始化程序的表达式中使用了所谓的指针算术。编译器确实不检查结果指针是否指向字符串文字之外。因此不会发出诊断。

于 2017-10-31T08:22:09.043 回答
0

因为添加 char litteral 'H' 就像向 char 添加任何其他有效的 char 值一样,而添加“Hello”意味着添加指向显然是不兼容类型的字符串的指针。

于 2017-10-31T08:20:27.290 回答