За пределами арифметики указатель не обнаружен? - PullRequest
2 голосов
/ 25 апреля 2019

Согласно Википедии и это , этот код неопределенного поведения:

#include <iostream>
int main(int, char**) {
    int data[1] = {123};
    int* p = data + 5; // undefined behavior
    std::cout << *(p - 5) << std::endl;
}

Скомпилировано с clang++-6.0 -fsanitize=undefined и выполнено, обнаружено неопределенное поведение, что является фантастическим, я получаю это сообщение:

ub.cpp:5:19: runtime error: index 5 out of bounds for type 'int [1]'

Но когда я не использую массив, неопределенное поведение не обнаруживается:

#include <iostream>
int main(int, char**) {
    int data = 123;
    int* p = &data + 5; // undefined behavior
    std::cout << *(p - 5) << std::endl;
}

Дезинфицирующее средство ничего не обнаруживает, хотя это все еще неопределенное поведение. Valgrind также не показывает никаких проблем. Есть ли способ обнаружить это неопределенное поведение?

Так как я никогда не получаю доступ к каким-либо недопустимым данным, это не дубликат Рекомендуемый способ отследить массив вне доступа / записи в программе C .

1 Ответ

4 голосов
/ 25 апреля 2019

Стандарт очень четко указывает, что большинство форм неопределенного поведения "не требует диагностики".Это означает, что ваш компилятор не обязан диагностировать UB (что также было бы неразумно, поскольку во многих случаях это очень трудно ).Вместо этого компилятору разрешено просто предполагать , что вы "конечно" не писали UB и генерировать код, как если бы вы этого не делали.И если вы сделали , это на вас, и вы сможете сохранить обломки.

Некоторые инструменты (например, asan и ubsan и повышение уровня предупреждения компиляторов до 11)обнаружить некоторые UB для вас.Но не все.

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

Один из способов обнаружить UB - это иметь интимное знание стандарта C ++ и читать код очень осторожно .Но вы не можете добиться большего успеха, чем это. Позвольте некоторым инструментам помочь вам найти низко висящие фрукты.Вы просто имеете чтобы знать ( all ) правила и знать, что вы делаете.

В C ++ нет тренировочных колес или подобных им предметов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...