9

你好!

我使用了以下C宏,但在C++中它不能自动void*转换为type*.

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

我知道,我可以这样做:

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

但我不想重写大部分代码,在哪里MALLOC_SAFE使用。

有没有办法在不给宏指定类型的情况下做到这一点?也许一些MSVC 2005 #pragma // __declspecother ?

ps:我不能使用 C 编译器,因为我的代码是大型项目的一部分(数百个模块之一)。现在它在 C++ 上。我知道,我可以单独构建我的代码。但这是旧代码,我只想快速移植它。

问题是关于 void* cast ;) 如果不可能,我将用 MACRO_SAFE_CPP 替换 MACRO_SAFE

谢谢你!

4

4 回答 4

36

为了使詹姆斯的回答更加肮脏,如果您没有decltype支持,您也可以这样做:

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);
}

然后:

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

我在我的博客上扩展了这个实用程序(在 C++11 中)。不要将它用于除邪恶之外的任何事情。

于 2010-10-26T20:31:31.480 回答
15

我不建议这样做;这是很糟糕的代码,如果你使用 C,你应该用 C 编译器编译它(或者,在 Visual C++ 中,作为 C 文件)

如果您使用的是 Visual C++,则可以使用decltype

#define MALLOC_SAFE(var, size)                      \
{                                                   \
    var = static_cast<decltype(var)>(malloc(size)); \
    if (!var) goto error;                           \
}
于 2010-10-26T20:24:54.553 回答
5

例如,像这样:

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; \
}
于 2010-10-26T20:58:37.403 回答
4

没有人只是强制转换var,你对 SAFE_MALOC() 的论点有什么原因吗?我的意思是,malloc()返回一个指针。你将它存储在一个接受指针的地方......其他人已经指出了各种简洁的类型安全的东西......我只是想知道为什么这不起作用:

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

是的,我知道。它病了,并且将类型安全抛到了窗外。但是直接((void *)(var))=强制转换并不总是有效。

于 2010-10-26T21:21:58.127 回答