C->C++ Automatically cast void pointer into Type pointer in C++ in #define in case of type is not given (C-style) [MSVS]

前端 未结 4 930
暗喜
暗喜 2021-02-15 15:00

Hi!

I\'ve used the following C macro, But in C++ it can\'t automatically cast void* to type*

相关标签:
4条回答
  • 2021-02-15 15:18

    I do not recommend doing this; this is terrible code and if you are using C you should compile it with a C compiler (or, in Visual C++, as a C file)

    If you are using Visual C++, you can use decltype:

    #define MALLOC_SAFE(var, size)                      \
    {                                                   \
        var = static_cast<decltype(var)>(malloc(size)); \
        if (!var) goto error;                           \
    }
    
    0 讨论(0)
  • 2021-02-15 15:22

    For example, like this:

    template <class T>
    void malloc_safe_impl(T** p, size_t size)
    {
        *p = static_cast<T*>(malloc(size));
    }
    
    #define MALLOC_SAFE(var, size) { \
        malloc_safe_impl(&var, size); \
        if (!var) goto error; \
    }
    
    0 讨论(0)
  • To makes James' answer even dirtier, if you don't have decltype support you can also do this:

    template <typename T>
    class auto_cast_wrapper
    {
    public:
        template <typename R>
        friend auto_cast_wrapper<R> auto_cast(const R& x);
    
        template <typename U>
        operator U()
        {
            return static_cast<U>(mX);
        }
    
    private:
        auto_cast_wrapper(const T& x) :
        mX(x)
        {}
    
        auto_cast_wrapper(const auto_cast_wrapper& other) :
        mX(other.mX)
        {}
    
        // non-assignable
        auto_cast_wrapper& operator=(const auto_cast_wrapper&);
    
        const T& mX;
    };
    
    template <typename R>
    auto_cast_wrapper<R> auto_cast(const R& x)
    {
        return auto_cast_wrapper<R>(x);
    }
    

    Then:

    #define MALLOC_SAFE(var, size)                      \
    {                                                   \
        var = auto_cast(malloc(size));                  \
        if (!var) goto error;                           \
    }
    

    I expanded on this utility (in C++11) on my blog. Don't use it for anything but evil.

    0 讨论(0)
  • 2021-02-15 15:39

    Is there a reason nobody just casts var, your argument to SAFE_MALOC()? I mean, malloc() returns a pointer. You're storing it somewhere that accepts a pointer... There are all sorts of neat type-safe things that other folks have already pointed out... I'm just wondering why this didn't work:

    #define MALLOC_SAFE(var,size)  {  \
        (* (void **) & (var)) = malloc(size); \
        if ( ! (var) ) goto error;    \
        }
    

    Yeah... I know. It's sick, and throws type-safety right out the window. But a straight ((void *)(var))= cast wouldn't always work.

    0 讨论(0)
提交回复
热议问题