禁用 c++ 的边界检查向量

发布于 2024-08-24 03:12:17 字数 382 浏览 10 评论 0原文

使用 stl::vector:

vector<int> v(1);
v[0]=1; // No bounds checking
v.at(0)=1; // Bounds checking

有没有一种方法可以禁用边界检查,而不必将所有 at() 重写为 []?我正在使用 GNU 标准 C++ 库。

编辑:我在怀疑存在瓶颈的区域将at()更改为[],它显着减少了计算时间。但是,由于我在开发代码和使用它运行实验之间进行迭代,因此我想在开发期间启用边界检查,并在实际运行实验时禁用它。我想安德鲁的建议是最好的解决方案。

With stl::vector:

vector<int> v(1);
v[0]=1; // No bounds checking
v.at(0)=1; // Bounds checking

Is there a way to disable bounds checking without having to rewrite all at() as []? I am using the GNU Standard C++ Library.

Edit: I changed at() to [] in the area where I suspected a bottleneck, and it significantly reduced the computation time. However, since I iterate between developing the code and running experiments with it, I would like to enable bounds checking during development and disable it when I run the experiments for real. I guess Andrew's advice is the best solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

没有伤那来痛 2024-08-31 03:12:17

如果你真的想这样做(至少是为了快速而肮脏的分析比较),如果你没有其他 at() ,

#define at(x) operator[](x)

并且如果你想保留 at() ,那么 这将起作用 用于开发并在生产中使用 operator[],只需将其包装在 #ifdef 中即可。

如果您确实有其他 at(),您可以随时编辑您的 #included 文件。

If you really want to do it (at least for a quick and dirty profiling comparison), this will work if you have no other at()s

#define at(x) operator[](x)

And if you want to keep at() for development and use operator[] in production, just wrap it in an #ifdef.

And if you do have other at()s you can always edit your #included <vector> file.

£冰雨忧蓝° 2024-08-31 03:12:17

不会。std::vector::at 的边界检查是由标准指定的,并且没有符合标准的 C++ 实现可以偏离该标准。

No. The bounds-checking of std::vector::at is specified by the standard, and there is no standard-conforming C++ implementation that can deviate from that.

初与友歌 2024-08-31 03:12:17

也许更好的解决方案是使用 [] 并使用标准库的检查实现进行调试。

Maybe a better solution is to use [] and use checked implementation of the standard library for debug.

情绪操控生活 2024-08-31 03:12:17

根据您想要打开/关闭边界检查的评论,您可以使用包装模板函数:

template <class T>
inline typename T::reference deref(T &cont, typename T::size_type idx)
{
#if BOUNDS_CHECK
    return cont.at(idx);
#else
    return cont[idx];
#endif
}

template <class T>
inline typename T::const_reference deref(const T &cont, typename T::size_type idx)
{
#if BOUNDS_CHECK
    return cont.at(idx);
#else
    return cont[idx];
#endif
}

您必须修改代码才能启用此功能,但是一旦您就位,您就可以打开或关闭边界检查如你所愿。

我承认它使用起来有点难看:

deref(vec, 10) = ...;

Based on your comment that you would like to turn on/off bounds checking, you could use a wrapper template function:

template <class T>
inline typename T::reference deref(T &cont, typename T::size_type idx)
{
#if BOUNDS_CHECK
    return cont.at(idx);
#else
    return cont[idx];
#endif
}

template <class T>
inline typename T::const_reference deref(const T &cont, typename T::size_type idx)
{
#if BOUNDS_CHECK
    return cont.at(idx);
#else
    return cont[idx];
#endif
}

You would have to modify your code to enable this, but once you had it in place you could turn bound checking on or off as you wish.

I do admit that it looks a bit ugly to use:

deref(vec, 10) = ...;
掌心的温暖 2024-08-31 03:12:17

使用 at() em>总是想要检查。另请注意,这会在错误时引发异常,因此它可能是可恢复的。如果您想要更快、未经检查的访问器,请使用 [],但是使用它的算法应该进行彻底的测试,因为故障模式更严重(未定义的行为)。

在 Linux 上使用 GCC 时,有几种方法对 [] 进行开发模式边界检查:

一些其他有趣的讨论:vector::at 与 vector::operator[]

Use at() when you always want checking. Also note that this throws an exception on error, so it is potentially recoverable. If you want the faster, unchecked, accessor, use [], but algorithms that use this should be tested thoroughly because the failure mode is more severe (undefined behavior).

A couple of approaches to development-mode bounds checking for [] when using GCC on Linux:

Some other interesting discussion: vector::at vs. vector::operator[]

榆西 2024-08-31 03:12:17

不是标准方式。您可以关闭编译器中的异常。您可以使用带有 -fno-exceptions 的 gcc 来完成此操作。

但你应该谨慎这样做;如果关闭异常,您的库(包括标准库)可能无法正常运行。检查您的文档,以及诸如 gcc 邮件列表上的这个主题。

Not a standard way. You could turn off exceptions in your compiler. You can do this with gcc with -fno-exceptions.

You should be wary of doing this though; your libraries (including the standard libraries) might not play nicely with exceptions turned off. Check your documentation, and threads like this one on the gcc mailing list.

守不住的情 2024-08-31 03:12:17

在您自己的命名空间中派生您自己的向量类,例如“uncheckedvector”,并覆盖基本向量类型的 at() 以使用数组索引。

然后使用“using uncheckedvector::vector”将让你覆盖所有地方对向量的使用。
如果您在任何地方使用完全限定类型,这将不起作用。

Derive your own vector class in your own namespace like "uncheckedvector", and override the at() of the base vector type to use the array index.

Then use "using uncheckedvector::vector" will let you override all your uses of vector everywhere.
This won't work if you're using fully qualified types anywhere though.

难得心□动 2024-08-31 03:12:17

如果您具有相当一致的访问模式(即/不是随机访问),而不是使用 at()[],避免范围检查的一种方法是使用迭代器,使用 begin()end()advance() 甚至更好,通过使用标准算法。

尽管这并不能解决纠正 at() 进行范围检查的根本问题,但标准库 (MSVC) 的某些实现已经检查了某些类型的构建的迭代器

If you have reasonably consistent access patterns (ie/ not random access), rather than using at() or [], one approach to avoid range checking is to use iterators, using begin(), end(), and advance() or even better, through the use of the standard algorithms.

Although this doesn't solve the underlying problem of correcting at() doing range checking some implementations of the standard library (MSVC) have checked iterators for some types of builds

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文