52

在什么情况下我们应该包括cassert

4

4 回答 4

47

简而言之,不要使用它;使用<assert.h>.

C++11 删除了“c....”标头不会污染全局命名空间的任何形式保证。

它从来都不是实践中的保证,现在甚至不是正式的保证。

因此,对于 C++11,使用“c....”头文件变体不再具有任何可以想象的优势,而与一个编译器和该编译器版本一起工作的代码可能会存在明显而明显的缺点。由于例如名称冲突或全局命名空间中的不同重载选择,无法使用其他编译器或版本进行编译。

所以,虽然cassert在 C++03 中毫无意义(你不能将宏放在命名空间中),但在 C++11 中它完全没有意义——即使作为一般方案的特例。


附录,2013 年 12 月 22 日:

该标准根据 <cX> 标头定义每个 C++ C 标头<Xh> 标头,而该标头又根据相应的 C 库标头定义。

C++11 §D.5/2

“每个 C 标头,每个都有一个形式的名称name.h,表现得好像每个由相应的cname标头放置在标准库命名空间中的名称都放置在全局命名空间范围内。”

C++11 §D.5/3(非规范示例):

“标头<cstdlib>确实在命名空间内提供了它的声明和定义std。它还可以在全局命名空间中提供这些名称。头文件<stdlib.h>在全局命名空间中确实提供了相同的声明和定义,就像在 C 标准中一样。它还可能在命名空间内提供这些名称std。”

Stack Overflow 用户CR的评论让我意识到某些版本的 g++,例如 MinGW g++ 4.7.2,在标头方面非常不标准<X.h>,缺少sinC++ 标准要求的重载:

我已经知道 MinGW g++ 4.7.2 也完全缺乏诸如 的功能swprintf,并且它在纯 C++ 库中也有同样的缺点,例如缺乏 C++11 std::to_string。然而,关于它缺少 C 函数重载的信息对我来说是新的。

在实践中,g++ 缺少重载意味着

  • 忽略 g++ 问题,或

  • 避免使用缺少的 g++ 重载,
    例如仅使用double sin( double ),或

  • 使用std命名空间重载
    (然后需要包含<cmath>以保证它们在 g++ 中的存在)。

为了使用std不合格的 g++ 命名空间重载,一种实用的方法是为此编译器定义标头包装器。我已经使用这种方法来解决 g++ 的缺点。给printf家人。正如大卫惠勒曾经说过的那样,“计算机科学中的所有问题都可以通过另一个层次的间接来解决”......

然后可以安排事情,以便使用 g++ 缺失重载的标准代码也可以使用 g++ 编译。这会将编译器调整为标准,并使用固定数量的代码。

于 2012-05-16T20:15:35.810 回答
8

就像任何其他头文件一样,#include <cassert>当您使用在该头文件中声明的内容时,例如assert().

于 2012-05-16T19:55:44.627 回答
0

查看易于访问的参考

#include <iostream>
// uncomment to disable assert()
// #define NDEBUG
#include <cassert>

int main()
{
    assert(2+2==4);
    std::cout << "Execution continues past the first assert\n";
    assert(2+2==5);
    std::cout << "Execution continues past the second assert\n";
}
于 2012-05-16T19:58:46.100 回答
0

assert.h 定义了一个可以用作标准调试工具的宏函数。

于 2013-12-22T06:22:50.257 回答