Невозможно быть абсолютно уверенным, что различные типы неопределенного поведения (в частности, в условиях гонки) не существуют.
Тем не менее, есть ряд инструментов, которые показывают множество таких ситуаций. Вы можете доказать, что в настоящее время существует проблема с такими инструментами, даже если вы не можете доказать, что ваше исправление действительно.
Несколько интересных инструментов для этой цели:
Valgrind это проверка памяти. Он обнаруживает утечки памяти, считывает неинициализированную память, использует висячие указатели и доступ за пределы.
Helgrind - это средство проверки безопасности потоков. Он находит условия гонки.
Оба работают с помощью динамического инструментария, то есть они принимают вашу программу как есть и выполняют ее в виртуализированной среде. Это делает их ненавязчивыми, но медленными.
UBSan - это неопределенная проверка поведения. Он находит различные случаи неопределенного поведения C и C ++, такие как целочисленные переполнения, сдвиги вне диапазона и тому подобное.
MSan это проверка памяти. У него такие же цели, как у Valgrind.
TSan - это проверка безопасности потока. У него те же цели, что и у Хелгринда.
Эти три встроены в компилятор Clang и генерируют код во время компиляции. Это означает, что вам нужно интегрировать их в процесс сборки (в частности, вам необходимо скомпилировать с Clang), что делает их первоначальную настройку намного сложнее, чем * grind, но, с другой стороны, они имеют гораздо меньшие накладные расходы времени выполнения.
Все перечисленные инструменты работают на Linux, а некоторые на MacOS. Я не думаю, что какая-либо работа над Windows пока надежна.