是否有没有未定义行为的安全版本的 C++?

Is there a safe version of C++ without undefined behaviour?

C++ 中的未定义行为真的很难调试。是否有一个版本的 C++ 和标准库不包含任何未定义的行为,而是抛出异常?我明白这将是一个性能杀手,但我只打算在调试模式下编程、调试和编译时使用这个版本,并不真正关心性能。理想情况下,此版本是可移植的,您将能够轻松切换 on/off 未定义的行为检查。

例如,您可以像这样实现一个安全指针 class(只检查空指针,如果它指向有效的内存块则不检查):

template <typename T>
class MySafePointer {
     T* value;
public:
      auto operator-> () {
          #ifndef DEBUG_MODE
          assert(value && "Trying to dereference a null pointer");          
          #endif
          return value;
      }
      /* Other Stuff*/

};

这里用户只需要#undef DEBUG_MODE如果你想找回你的表现。

是否有 C++ 的库/安全版本可以执行此操作?

编辑:更改了上面的代码,使其实际上更有意义并且不会抛出异常但断言值不为空。问题只是描述性错误消息与崩溃的问题...

Is there a version of c++ and standard library which does not contain any undefined behaviour but rather throws exceptions?

不,没有。正如评论中提到的,有 Address Sanitizer 和 Undefined Behavior Sanitizer 以及许多其他可用于查找错误的工具,但没有“没有未定义行为的 C++”实现。

如果您想要一种本质上安全的语言,请选择一种。 C++ 不是吗。

Is there a safe version of c++ without undefined behaviour?

没有

For example, you could implement a safe pointer class like so

抛出异常比仅仅崩溃更安全?您仍在尝试找到 错误以便静态修复它,对吧?

你写的东西允许你的错误程序保持 运行(除非它只是调用 terminate,在这种情况下你做了一些工作根本没有结果),但这并没有它是正确的,它隐藏了错误而不是帮助你修复它。

Is there a library / safe version of C++ which does this?

未定义行为只是错误的一种,并不总是错误。故意使用非便携式平台功能也可能是标准 未定义

无论如何,假设您捕获了每个未初始化的值和空指针以及有符号整数溢出 - 您的程序仍然会产生错误的结果。

如果您编写的代码不会产生错误的结果,那么它也不会有 UB。

未定义的行为

未定义的行为意味着您的程序最终处于标准未定义其行为的状态。

所以你真正想问的是,是否有一种语言的标准定义了每一种可能的场景。

而且我想不出一种这样的语言,原因很简单,程序 运行 是由机器编写的,而程序和标准是由人类编写的。

在一些微不足道的情况下防止它的影响

未定义行为的一个微不足道的例子是当您通过 operator[] 访问 std::vector 的越界元素时。与 C 风格的数组完全一样,v[i] 基本上返回 *(v_ + i),其中 v_ 是包裹在 v 中的指针。这速度快而且不安全。

如果你想安全地访问第i个元素怎么办?您将不得不 更改 std::vector<>::operator[].

的实施

那么支持 DEBUG_MODE 标志会产生什么影响?本质上,您必须编写两个由 #ifdef/(#else/)#endif 分隔的实现。显然这两个实现有很多共同点,因此您可以在代码中多次 #-branch。但是......是的,我的底线是你的要求可以通过改变标准来满足,这种方式迫使实施者支持两种不同的实施(安全和 fast/unsafe 和慢)。

顺便说一句,对于这种特定情况,标准确实定义了另一个函数,at,它是处理越界情况所必需的。但这就是重点:这是另一个功能。

疑惑

我最近发现 this question about UB as related to constexpr. Here's a little quote from the answer by Nicol Bolas,

Hypothetically, we could rip all undefined behavior out of C++ or even C. We could have everything be a priori well-defined and remove anything from the language whose evaluation could not be definitely determinable from first principles.

这让我对我在这里给出的答案感到紧张。