根据编译开关/ NDEBUG

时间:2015-07-22 10:47:18

标签: c++ clang++

我知道g ++(和MSVC)具有允许对operator []进行边界检查的开关,遗憾的是,据我所知,LLVM的libc ++并没有完全实现这样的开关或调试代码。

在我当前的项目中,我一直在使用我自己的vector实现(几年前我写的可移植性),它不会抛出异常,并且对operator []和(实际上)有基于断言的边界检查一个调用另一个,它们的行为相同,因为没有例外)。

在我完成当前程序后,我将会移交此代码库,并且可能会在很长一段时间内使用。由于我不应该被要求维护它或任何我想在任何地方完全符合标准,我不觉得重新实施容器是符合标准的精神,(我也高度怀疑我的容器和libc ++或libstdc ++团队编写的容器一样好。

我是否可以使用一些预处理器魔法或类似物来使operator []在调试期间表现得像at()因为未捕获的异常导致中止(并且当我禁用此调试模式时,它的行为类似于operator [])? (项目完全支持C ++ 14)

2 个答案:

答案 0 :(得分:7)

我们可以从the trunk libc++ source code for vector看到std::vector<>::operator[]内确实有这样的检查,通过_LIBCPP_ASSERT

不幸的是,the libc++ debug feature is not yet functional

所以:

  • 关注libc ++更新
  • 训练您的团队期待 operator[]默默接受损坏的输入。根据定义,这就是它的作用。依赖于特定于实现的附加健全性检查是一个非常糟糕的主意。如果他们不确定他们在做什么,你的团队应该写自己的断言。

答案 1 :(得分:-1)

  

我是否可以使用一些预处理器魔法或类似物来使operator []在调试期间表现得像at()因为未捕获的异常导致中止(并且当我禁用此调试模式时,它的行为类似于operator [])? (项目完全支持C ++ 14)

呃......这个怎么样?

const T& your_vector::operator[](std::size_t index) const
{
#ifndef NDEBUG // !! double negative condition
    if(index >= size_) // assume size_ is std::size_t size_; member of class
        throw std::out_of_bounds{"const T& your_vector::operator[]"};
#endif
    return data_[index]; // assume data_ is a native array containing the elements
}

const T& your_vector::at(std::size_t index) const
{
    if(index >= size_) // assume size_ is std::size_t size_; member of class
        throw std::out_of_bounds{"const T& your_vector::at"};
    return data_[index]; // assume data_ is a native array containing the elements
}

定义DEBUG时索引操作符实现与at相同,未定义宏时更快。