是否有没有未定义行为的安全版本的 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.
这让我对我在这里给出的答案感到紧张。
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.
这让我对我在这里给出的答案感到紧张。