BOOST_STATIC_WARNING [英] BOOST_STATIC_WARNING

查看:173
本文介绍了BOOST_STATIC_WARNING的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近遇到了一些麻烦与C ++的隐式转换,所以我在寻找一种方式来警告人们,如果有人试图将一个int32_t分配给uint64_t中或什么的。 BOOST_STATIC_ASSERT 将创造奇迹对于这一点,除了code碱基我工作是相当大的,它依赖于大量的隐式转换,所以立即打破一切断言是不现实的。

它看起来像 BOOST_STATIC_WARNING 会非常适合我,但是,我不能让它真正发出警告。这样的事不会做任何事情:

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

我的编译器是G ++ 4.4.3与--std =的C ++ 0x -Wall -Wextra。我升压为1.46.1。


我想在这里解决的问题是,我们有像 uint8_t有GetUInt8(SIZE_TYPE指数)无效方法缓冲类型SetUInt32(SIZE_TYPE指数,uint32_t的值)等,所以,你看到这样的用法:

  X = buffer.GetUInt16(96);

问题是,有没有保证,而你正在阅读的16位无符号整数,即 X 实际上是16位。虽然谁最初写这句话的人做了正确的(希望如此),如果类型X 的变化,这条线将打破静默。

我的解决方案是创建一个 safe_convertable< T> 键入像这样:

 模板< typename的T>
结构safe_convertable
{
上市:
    模板< typename的TSource>
    safe_convertable(常量TSource&放大器; VAL)
    {
        TYPEDEF提振:: is_same< T,TSource> same_type;
        BOOST_STATIC_WARNING(same_type ::值);        _val = VAL;
    }    模板< typename的TDestination>
    运营商TDestination()
    {
        TYPEDEF提振:: is_same< T,TDestination> same_type;
        BOOST_STATIC_WARNING(same_type ::值);        返回_val;
    }
私人的:
    Ť_val;
};

和改变方法,以返回并接受这些安全引用: safe_reference< uint8_t有> GetUInt8(SIZE_TYPE指数)无效SetUInt32(SIZE_TYPE指数,safe_reference< uint32_t的>值)(这是短版,也有其他运营商和诸如此类的东西你可以做参考)。

反正这个伟大工程与 BOOST_STATIC_ASSERT ,保存,我想警告,而不是错误的情况。


有关的好奇,我已经实现了预警的事情我自己,这工作得很好,但我preFER Boost的品种,使我得到的所有其他升压功能(函数内部这只作品)。

 详细的命名空间
{
    模板< typename的TIntegralContant>
    内嵌无效test_warning(常量TIntegralContant&安培;)
    {
        的static_cast<无效>(1 / TIntegralContant ::值);
    }
}#定义MY_STATIC_WARNING(VALUE_)\\
    ::详细:: test_warning(::的boost :: integral_constant<布尔,VALUE_>())


解决方案

您正在使用什么版本的Boost?这一评论可能是为什么您自己的警告工作的原因,但增压版本不会:

  // 6.替换实施与其中一个只取决于
// MPL ::打印<&GT ;.在previous人被发现失败的功能
//最新版本的GCC和英特尔编译器的下 - 罗伯特·雷米

如果您升级到最新版的提升(例如1.46.1)我猜,你会好到哪里去。的手指穿过

I've recently had some trouble with C++'s implicit casting, so I'm looking for a way to warn people if somebody attempts to assign an int32_t to a uint64_t or whatever. BOOST_STATIC_ASSERT would work wonders for this, except that the code base I'm working with is quite large and relies on a lot of implicit casting, so immediately breaking everything with assertions is unrealistic.

It looks like BOOST_STATIC_WARNING would be ideal for me, however, I cannot get it to actually emit a warning. Something like this won't do anything:

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

My compiler is g++ 4.4.3 with --std=c++0x -Wall -Wextra. My Boost is 1.46.1.


The problem I'm trying to solve here is that we have a buffer type which has methods like uint8_t GetUInt8(size_type index), void SetUInt32(size_type index, uint32_t value), etc. So, you see usage like this:

x = buffer.GetUInt16(96);

The problem is that there is no guarantee that, while you are reading a 16-bit unsigned integer, that x is actually 16-bits. While the person who originally wrote that line did it properly (hopefully), if the type of x changes, this line will break silently.

My solution is to create a safe_convertable<T> type like so:

template <typename T>
struct safe_convertable
{
public:
    template <typename TSource>
    safe_convertable(const TSource& 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;
};

and change the methods to return and accept these safe references: safe_reference<uint8_t> GetUInt8(size_type index), void SetUInt32(size_type index, safe_reference<uint32_t> value) (that's the short version, there are other operators and whatnot you can do to references).

Anyway, this works great with BOOST_STATIC_ASSERT, save for the fact that I want warnings and not errors.


For the curious, I've implemented the warning thing myself, which works fine, but I'd prefer the Boost variety so that I get all the other Boost features (this only works inside a function).

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

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

解决方案

What version of Boost are you using? This comment may be the reason why your own warning works, but the boost version does not:

// 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

I'm guessing if you upgraded to a recent version of Boost (e.g. 1.46.1), you'd be good to go. crosses fingers

这篇关于BOOST_STATIC_WARNING的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆