BOOST_STATIC_WARNING

#c #boost #compiler-warnings

#c #повышение #предупреждения компилятора

Вопрос:

Недавно у меня возникли некоторые проблемы с неявным приведением C , поэтому я ищу способ предупредить людей, если кто-то попытается присвоить int32_t uint64_t или что-то еще. BOOST_STATIC_ASSERT это сотворило бы чудеса для этого, за исключением того, что кодовая база, с которой я работаю, довольно большая и опирается на множество неявных приведений, поэтому немедленное нарушение всего с помощью утверждений нереально.

Похоже, что BOOST_STATIC_WARNING было бы идеально для меня, однако я не могу заставить его фактически выдавать предупреждение. Что-то вроде этого ничего не даст:

     typedef boost::is_same<int64_t, int32_t> same_type;
    BOOST_STATIC_WARNING(same_type::value);
  

Моим компилятором является g 4.4.3 с —std=c 0x -Wall -Wextra. Мой Boost равен 1.46.1.


Проблема, которую я пытаюсь решить здесь, заключается в том, что у нас есть тип буфера, который имеет такие методы, как uint8_t GetUInt8(size_type index) , void SetUInt32(size_type index, uint32_t value) и т.д. Итак, вы видите использование следующим образом:

 x = buffer.GetUInt16(96);
  

Проблема в том, что нет гарантии, что при чтении 16-разрядного целого числа без знака это x на самом деле 16 бит. Хотя человек, который изначально написал эту строку, сделал это правильно (надеюсь), если тип x изменится, эта строка будет автоматически прерываться.

Мое решение состоит в том, чтобы создать safe_convertable<T> тип, подобный этому:

 template <typename T>
struct safe_convertable
{
public:
    template <typename TSource>
    safe_convertable(const TSourceamp; val)
    {
        typedef boost::is_same<T, TSource> same_type;
        BOOST_STATIC_WARNING(same_type::value);

        _val = val;
    }

    template <typename TDestination>
    operator TDestination ()
    {
        typedef boost::is_same<T, TDestination> same_type;
        BOOST_STATIC_WARNING(same_type::value);

        return _val;
    }
private:
    T _val;
};
  

и измените методы, чтобы возвращать и принимать эти безопасные ссылки: safe_reference<uint8_t> GetUInt8(size_type index) , void SetUInt32(size_type index, safe_reference<uint32_t> value) (это сокращенная версия, есть другие операторы и еще много чего, что вы можете сделать со ссылками).

В любом случае, это отлично работает с BOOST_STATIC_ASSERT , за исключением того факта, что мне нужны предупреждения, а не ошибки.


Для любопытных, я сам реализовал функцию предупреждения, которая работает нормально, но я бы предпочел вариант Boost, чтобы получить все остальные функции Boost (это работает только внутри функции).

 namespace detail
{
    template <typename TIntegralContant>
    inline void test_warning(const TIntegralContantamp;)
    {
        static_cast<void>(1 / TIntegralContant::value);
    }
}

#define MY_STATIC_WARNING(value_) 
    ::detail::test_warning(::boost::integral_constant<bool, value_ >())
  

Комментарии:

1. «Я не могу заставить его на самом деле выдавать предупреждение. Что-то вроде этого ничего не даст:»

2. @Nawaz: Он написал «Я не могу заставить его на самом деле выдавать предупреждение».

3. @Travis: Он выдает предупреждение с помощью g 4.3.4 : ideone.com/68yOM … поскольку в ideone нет boost для c 0x , поэтому я не могу скомпилировать его с --std=c 0x опцией.

4. Зачем вам предупреждение, если вы не собираетесь устранять проблему? Это просто добавило шума.

5. @Bo: Я исправлю проблему, я просто не хочу прерывать сборки в то же время. Это проблемы, которые необходимо исправить, просто не немедленно .

Ответ №1:

Какую версию Boost вы используете? Этот комментарий может быть причиной того, что ваше собственное предупреждение работает, но версия boost этого не делает:

 // 6. replaced implementation with one which depends solely on
//    mpl::print<>.  The previous one was found to fail for functions
//    under recent versions of gcc and intel compilers - Robert Ramey
  

Я предполагаю, что если бы вы обновились до последней версии Boost (например, 1.46.1), все было бы в порядке. скрещивает пальцы

Комментарии:

1. Ого! Вот и вся эта идея. Не возражаете против регистрации ошибки?