问题
Hi!
I've used the following C macro, But in C++ it can't automatically cast void*
to 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.
Is there any way to do this without giving the type to the macro? Maybe some MSVC 2005 #pragma
/__declspec
/other ?
p.s.: I can't use C compiler, because my code is part (one of hundreds modules) of the large project. And now it's on 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
Thank You!
回答1:
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; \
}
回答2:
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.
回答3:
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; \
}
回答4:
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.
来源:https://stackoverflow.com/questions/4027604/c-c-automatically-cast-void-pointer-into-type-pointer-in-c-in-define-in-ca