Можно ли включить проверку границ массивов в g ++? - PullRequest
15 голосов
/ 24 января 2011

Возможно ли, чтобы g ++ показывал ошибку при компиляции следующего файла с некоторым флагом?

#include <iostream>
using namespace std;

int main()
{
   int arr[ 2 ];

   cout << arr[ 4 ] << endl;

   return 0;
}

Я видел некоторые вещи, такие как gcc -Wall -O2 main.c, который работает только с C, а не с C ++.

Ответы [ 5 ]

7 голосов
/ 24 января 2011

Не во время компиляции. Вы можете проверить это во время выполнения.

Для этого взгляните на: Проверка границ массива во время выполнения с g ++

3 голосов
/ 24 января 2011

Вы можете использовать статический анализатор, такой как Cppcheck . Когда запустите ваш код выше:

$ cppcheck --enable=all test.cpp
Checking test.cpp...
[test.cpp:6]: (style) Variable 'arr' is not assigned a value
[test.cpp:8]: (error) Array 'arr[2]' index 4 out of bounds

Вы можете интегрировать Cppcheck в процедуру сборки и считать, что ваш код успешно собран, только если Cppcheck прошел.

3 голосов
/ 24 января 2011

Для необработанных массивов я так не думаю, потому что -fbounds-check не работал с вашим примером и MingW g ++ 4.4.1, а также потому, что у меня есть старые документы 3.x, которые я говорю

-fbounds-check

Для внешних интерфейсов, которые его поддерживают, сгенерируйте дополнительный код, чтобы проверить, что индексы, используемые для доступа к массивам, находятся в заявленном диапазоне.В настоящее время это поддерживается только внешними интерфейсами 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 <b>-D _GLIBCXX_DEBUG -D _GLIBCXX_DEBUG_PEDANTIC</b> & a
c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/debug/vector:265:
    error: attempt to subscript container with out-of-bounds index 4, but
    container only holds 2 elements.

Objects involved in the operation:
sequence "this" @ 0x0x22ff1c {
  type = NSt7__debug6vectorIiSaIiEEE;
}

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

C:\test> _

Сообщается дляв новых версиях g ++ (после 4.0) вам не нужен символ _GLIBCXX_DEBUG_PEDANTIC.Подробнее см. Документацию GNU .

Приветствия и hth.,

2 голосов
/ 24 января 2011

Я помню, как увидел предупреждение gcc или g ++ из ffmpeg или x264 по строкам

"индекс предупреждения массива может быть вне границ"

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

кажется, что он, вероятно, сделал это.

Ограничение в том, что у вас есть пример, подобный вашему выше.как только у вас есть переменные вместо литералов, это невозможно.кроме, возможно, в простой петле.

0 голосов
/ 24 января 2011

Вы можете заменить массивы на std::vector. Vector имеет функцию-член (std::vector::at), которая выполняет проверку границ во время выполнения.

К сожалению, проверка времени компиляции на предмет переполнения буфера является очень сложной неразрешимой проблемой. Обычно он обрабатывается полнофункциональным инструментом статического анализа.

...