Дезинфицирующим средствам Clang не хватает чтения из неинициализированной памяти
У меня есть следующий код, который, я уверен, считывается из памяти мусора, но дезинфицирующие средства clang не жалуются.
Могу ли я что-то сделать, чтобы они сработали, или я должен просто принять это как ограничение / ошибку?
#include <algorithm>
#include <iostream>
#include <vector>
struct B{
int x;
};
struct D : public B{
short y;
D& operator = (const D& other) {
y = other.y;
return *this;
}
};
int main() {
D var1{4,7},var2;
var2=var1;
std::cout << var2.x << " " << var2.y << std::endl;
}
Я пробовал установить O0, поскольку это иногда помогает, но на этот раз не помогло.
Я также открыт для использования gcc, но я думаю, что в gcc нет очистителя памяти, только asan.
1 ответ
Из документации
Неинициализированные значения возникают, когда память, выделенная стеком или кучей, считывается перед записью. MSan обнаруживает случаи, когда такие значения влияют на выполнение программы.
MSan является битовым: он может отслеживать неинициализированные биты в битовом поле. Он допускает копирование неинициализированной памяти, а также простые логические и арифметические операции с ней. Как правило, MSan автоматически отслеживает распространение неинициализированных данных в памяти и сообщает предупреждение, когда выполняется (или не выполняется) ветвь кода, в зависимости от неинициализированного значения.
То есть, чтобы свести к минимуму ложные срабатывания, прежде чем жаловаться, clang ждет, пока не убедится, что неинициализированная память действительно влияет на выполнение программы (берет другую ветвь, возвращает другое значение, отличное от основного и т. Д.). Копирование неинициализированной памяти могло быть безобидным.
В вашей конкретной программе фактическое использование неинициализированного значения происходит в стандартной библиотеке, возможно, даже только в библиотеке C, которая не была оснащена MSan, поэтому вы не получите предупреждения.
Очень важно собрать весь код в вашей программе (включая библиотеки, которые она использует, в частности, стандартную библиотеку C++) с помощью MSan.
Это ограничение является основной причиной того, что это дезинфицирующее средство гораздо менее популярно, чем, скажем, ASan или UBSan.
Чтобы вернуться к этой простой программе, различные инструменты статического анализа могут обнаружить проблему, даже просто
g++ -Wall -O
будет предупреждать, но имейте в виду, что ложные срабатывания не редкость.
x.cc: In function 'int main()':
x.cc:20:28: warning: 'var2.D::<anonymous>.B::x' is used uninitialized [-Wuninitialized]
20 | std::cout << var2.x << " " << var2.y << std::endl;
| ^~~~~