简体   繁体   English

C-> C ++在未定义类型的情况下,在#define中自动将void指针转换为C ++中的Type指针(C样式)[MSVS]

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

Hi! 嗨!

I've used the following C macro, But in C++ it can't automatically cast void* to type* . 我使用了以下C宏,但是在C ++中,它不能自动将void*type*

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

I know, I can do something like this: 我知道,我可以做这样的事情:

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

But I don't want to rewrite a big portion of code, where MALLOC_SAFE was used. 但是我不想重写使用MALLOC_SAFE大部分代码。

Is there any way to do this without giving the type to the macro? 有没有办法不给宏指定类型的方法吗? Maybe some MSVC 2005 #pragma / __declspec /other ? 也许一些MSVC 2005 #pragma / __declspec / other?

ps: I can't use C compiler, because my code is part (one of hundreds modules) of the large project. ps:我不能使用C编译器,因为我的代码是大型项目的一部分(数百个模块之一)。 And now it's on C++. 现在它在C ++上。 I know, I can build my code separately. 我知道,我可以分别构建代码。 But it's old code and I just want to port it fast. 但这是旧代码,我只想快速移植。

The question is about void* casting ;) If it's not possible, I'll just replace MACRO_SAFE with MACRO_SAFE_CPP 问题是关于void *强制转换;)如果不可能,我将用MACRO_SAFE_CPP替换MACRO_SAFE

Thank You! 谢谢!

To makes James' answer even dirtier, if you don't have decltype support you can also do this: 为了使James的答案更加肮脏,如果您没有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);
}

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 . 我在Blog上扩展了该实用程序(在C ++ 11中)。 Don't use it for anything but evil. 不要将其用于邪恶。

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) 这是很糟糕的代码,如果您使用的是C,则应使用C编译器(或在Visual C ++中,作为C文件)进行编译。

If you are using Visual C++, you can use decltype : 如果您使用的是Visual C ++,则可以使用decltype

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

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

Is there a reason nobody just casts var , your argument to SAFE_MALOC()? 有没有人没有理由将var转换为SAFE_MALOC()的原因? I mean, malloc() returns a pointer. 我的意思是, malloc()返回一个指针。 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. 但是直接((void *)(var))=强制转换并不总是有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM