C++字符串(常量字符[1])到布尔类型的转换 - 原因/解释和后果

C++ string (const char[1]) to bool type conversion - reason/explanation and consequences

本文关键字:转换 类型 原因 后果 解释 布尔 常量 字符串 字符 C++      更新时间:2023-10-16

看看下面的C++代码:

// imagine 10.000 lines if C++ here
bool test() {
   // imagine 300 loc here 
   return "";
}
int main(int argc, char** argv) {
    bool whaaaaaat = test();
    return 0;
}

编译这些行时,结果为:

BUILD SUCCESSFUL (total time: 208ms)

甚至没有警告!

请确认:

  1. " 被编译器视为 char[1] 又名 char* C++
  2. 然后将其转换为布尔值
  3. 总是 != 0 => 总是正确的

问题:当程序继续时,是否会对程序的状态产生任何负面影响(内存损坏?

这种设置真的很危险,编译器至少应该给出警告!

你基本上是对的。

字符串文字char const[1]将衰减为char const*,与任何指针一样,布尔化将告诉您它是否为 null。这个不是。

我通常倾向于同意这种隐式转换是危险的,但这只是因为你的程序的行为可能不是你想要的。没有"破碎的记忆"。

" 被编译器视为 char[1] 又名 char* C++

用非常不准确的术语来说,是的。更准确地说,""是一个const char[1],常量字符数组可以衰减到指向第一个(仅在这种情况下)字符的const char*

然后将其转换为布尔值

总是 != 0 => 总是正确的

完全是的,对两者都有。

问:当程序继续时,是否会对程序的状态产生任何负面影响(内存损坏?

没有损坏的记忆或任何其他负面影响。行为是明确定义的。此函数实际上相同:

bool test() {
    "";
    return true;
}

这种设置真的很危险

我不同意。最多没意义。

问题是关于一个返回始终为 true 的函数,没有任何编译器的警告或错误,这只是精简示例。

我认为这不需要警告,更不用说错误了。

考虑一个接口,它是对不同类型进程的抽象,在成功时返回 true。现在考虑实现该接口,知道您的简单过程永远不会失败,因此始终返回 true。编译器是否应该阻止您编写此类实现?它甚至应该用警告来纠缠你吗?在我看来不是。

您认为GDB可能会受到影响吗?

不。

""被编译器视为char[1] C++又名char**

""被视为一个常数char的数组。它与char*不同,尽管在某些情况下它可以转换为const char*(常量是特定于C++的)。

然后将其转换为始终!= 0 => 始终truebool

在这两点上都正确。

当程序继续时,是否会对程序的状态产生任何负面影响(内存损坏?

这绝对没有任何后果:没有内存泄漏,没有悬空的指针或其他不好的事情。

没有负面影响,只是糟糕(太难理解)的编码风格。我在多年的旧工作项目中看到了这样的代码

assert(somethingIsRight && "Something is wrong!");

它被很好地定义为布尔转换(隐式转换之一):

整数、浮点、无作用域枚举、指针、 并且指向成员的指针类型可以转换为类型的 prvalue 布尔。

值零(对于积分、浮点和无作用域 枚举)和空指针和空指针指向成员 值变为假。所有其他值都变为 true。

对于您的代码,""可能会衰减到指针(即 const char* ) 不为空,因此结果将为 true 。对于指针,它只是检查它是否为 null 并返回一个truefalsebool,它会没问题(没有"损坏的内存":))。