Я компилирую проект, включающий библиотеку asio C++, и получаю неприятное предупреждение:
../opendnp3/_deps/asio-src/asio/include/asio/impl/connect.hpp:75:73:
warning: ‘this’ pointer is null [-Wnonnull]
75 | (*static_cast<legacy_connect_condition_helper<T, Iterator>*>(0))(
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
76 | *static_cast<const asio::error_code*>(0),
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
77 | *static_cast<const Iterator*>(0)))) != 1;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
В приведенном ниже коде файл asio Connect.hpp (строка 67)
template <typename T, typename Iterator>
struct is_legacy_connect_condition
{
static char asio_connect_condition_check(char);
static char (&asio_connect_condition_check(Iterator))[2];
static const bool value =
sizeof(asio_connect_condition_check(
(*static_cast<legacy_connect_condition_helper<T, Iterator>*>(0))(
*static_cast<const asio::error_code*>(0),
*static_cast<const Iterator*>(0)))) != 1;
};
Я слишком новичок в шаблонах, чтобы диагностировать это предупреждение. Кто-нибудь сталкивался с этим и/или имел какое-либо представление о том, указывает ли это на реальную проблему и как я могу предотвратить предупреждение? (На самом деле существует несколько подобных предупреждений, что добавляет много беспорядка в вывод.) Спасибо.
Он находится в неоцененном контексте (внутри sizeof
), так что это не проблема.
Ускорение обновления. Начиная с версии 1.78 вместо этого используется static const bool value = sizeof(asio_connect_condition_check( (declval<legacy_connect_condition_helper<T, Iterator> >())(declval<const boost::system::error_code>(), declval<const Iterator>()))) != 1;
.
По моему мнению, лучший способ отключить это предупреждение — изменить процесс сборки таким образом, чтобы путь загрузки включался с помощью переключателя -isystem
. Таким образом, предупреждения из заголовков повышения будут игнорироваться.
No Non Null звучит как имя плохого парня, когда Стэн Ли писал комиксы о монстрах в 50-х годах.
Boost 1.85.0 — текущая версия Boost. Эта проблема была исправлена в версии 1.78.0 (08 декабря 2021 г.). Какую версию Boost вы используете?
Это проверка того, является ли результат вызова legacy_connect_condition_helper<T, Iterator>
Iterator
или нет, что, в свою очередь, проверяет, является ли T
функцией, которая принимает error_code
и Iterator
и возвращает Iterator
.
Однако важно то, что не имеет значения, что указатели имеют значение null, поскольку sizeof
— это неоцениваемый контекст. Имеют значение только задействованные типы; выражение не выполняется, и поэтому все эти разыменования нулевого указателя безопасны.
В более современном коде вы, вероятно, использовали бы std::declval
вместо приведения нулевых указателей:
template <typename T, typename Iterator>
struct is_legacy_connect_condition
{
static char asio_connect_condition_check(char);
static char (&asio_connect_condition_check(Iterator))[2];
static const bool value =
sizeof(asio_connect_condition_check(
(std::declval<legacy_connect_condition_helper<T, Iterator>>())(
std::declval<const asio::error_code>(),
std::declval<const Iterator>()))) != 1;
};
Но std::declval
не был представлен до C++11. Asio довольно старый, и ему приходилось работать на старых компиляторах без поддержки C++11.
Что касается того, как избежать предупреждения, лучше всего обновиться до более новой версии asio. Нарушающий код был заменен версией declval
в этом коммите три года назад и был выпущен как часть автономной версии asio 1.21.0 или boost 1.78.
Если по какой-то причине вы застряли на старой версии и используете GCC, вы можете добавить каталоги asio include в качестве системных (используйте -isystem
вместо -I
). Это отключит отчеты о предупреждениях для этих заголовков (в основном).
В противном случае вам придется глобально отключить предупреждение о ненулевых значениях. Либо прекратите передачу -Wnonnull
, либо добавьте -Wno-nonnull
(если ненулевое значение включено каким-либо другим предупреждающим флагом).
Не уверен, что это то, что вам нужно, но
-Wno-nonnull
отключит это конкретное предупреждение.