【问题标题】:Is it possible to enable array bounds checking in g++?是否可以在 g++ 中启用数组边界检查?
【发布时间】:2011-06-14 07:03:43
【问题描述】:

在编译带有一些标志的以下文件时,是否可以让 g++ 显示错误?

#include <iostream>
using namespace std;

int main()
{
   int arr[ 2 ];

   cout << arr[ 4 ] << endl;

   return 0;
}

我看到了一些像 gcc -Wall -O2 main.c 这样的东西,它只适用于 C,而不适用于 C++。

【问题讨论】:

  • -Wall -Wextra -ansi -pedantic 不要为此程序生成警告:(

标签: g++ c++


【解决方案1】:

不是在编译时。不过,您也许可以在运行时检查。

为此,请查看: Runtime array bounds checking with g++

【讨论】:

    【解决方案2】:

    您可以用std::vector 替换数组。 Vector 具有在运行时进行边界检查的访问器成员函数 (std::vector::at)。

    不幸的是,缓冲区溢出的编译时检查是一个非常难以确定的问题。它通常由成熟的静态分析工具处理。

    【讨论】:

      【解决方案3】:

      我记得看到来自 ffmpeg 或 x264 的 gcc 或 g++ 警告消息,类似于

      “数组的警告索引可能超出范围”

      http://gcc.gnu.org/ml/gcc/2000-07/msg01000.html

      似乎它可能成功了。

      限制是你有一个像上面这样的例子。一旦你有变量而不是文字,这是不可能的。除了可能在一个简单的循环中。

      【讨论】:

      【解决方案4】:

      对于原始数组,我不这么认为,因为 -fbounds-check 不适用于您的示例和 MingW g++ 4.4.1,并且因为我说过旧的 3.x 文档

      -fbounds-检查

      对于支持它的前端, 生成额外的代码来检查 用于访问数组的索引是 在声明的范围内。这是 目前仅由 Java 支持 和 Fortran 77 前端,这里 选项默认为 true 和 false 分别。

      但是,使用std::vector,您可以使用at 进行稍微不切实际的运行时边界检查(生成异常)。您可以使用标准库的特殊调试版本,它为[] 提供实用的运行时边界检查。比如编译的时候……

      #include <iostream>
      #include <vector>
      using namespace std;
      
      int main()
      {
         vector<int>  arr( 2 );
      
         cout << arr[ 4 ] << endl;
      }
      

      ...对于 g++ 标准库实现的发布和调试版本,您会分别获得不同的非检查和检查行为:

      C:\test> g++ x.cpp & a 4083049 C:\test> g++ x.cpp -D _GLIBCXX_DEBUG -D _GLIBCXX_DEBUG_PEDANTIC & a c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/debug/vector:265: 错误:尝试使用越界索引 4 下标容器,但是 容器仅包含 2 个元素。 操作中涉及的对象: 序列“这个”@ 0x0x22ff1c { 类型 = NSt7__debug6vectorIiSaIiEEE; } 此应用程序已请求运行时以不寻常的方式终止它。 请联系应用程序的支持团队以获取更多信息。 C:\测试> _

      据报道,对于较新的 g++ 版本(4.0 之后),您不需要 _GLIBCXX_DEBUG_PEDANTIC 符号。详情请见GNU documentation

      干杯,

      【讨论】:

      • {boost,std::tr1,std}::array 也有 at
      • -fbounds-check 似乎仅在启用优化时才有效。所以我希望-O -fbounds-check 能够工作 - 但它并没有像你说的那样在 OP 的例子中。然而-fsanitize=address,undefined 确实抓住了它:godbolt.org/z/5MPx3d668
      【解决方案5】:

      您可以使用静态分析器,例如 Cppcheck。在上面的代码上运行时:

      $ cppcheck --enable=all test.cpp 检查 test.cpp... [test.cpp:6]:(样式)变量“arr”未赋值 [test.cpp:8]:(错误)数组 'arr[2]' 索引 4 超出范围

      您可以将 Cppcheck 集成到您的构建过程中,并且只有在 Cppcheck 通过时才认为您的代码构建成功。

      【讨论】:

        猜你喜欢
        • 2013-09-23
        • 1970-01-01
        • 1970-01-01
        • 2018-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多