C-> C ++ fundido automáticamente el puntero nulo en un tipo de puntero en C ++ en #define en el caso del tipo no se da (C-estilo) [MSVS]

StackOverflow https://stackoverflow.com/questions/4027604

Pregunta

¡Hola!

He utilizado el siguiente C macro, pero en C ++ que no puede lanzar automáticamente void* a type*.

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

Lo sé, lo puedo hacer algo como esto:

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

Pero no quiero volver a escribir una gran porción de código, donde se utilizó MALLOC_SAFE.

¿Hay alguna manera de hacer esto sin dar el tipo de la macro? Tal vez algunos MSVC 2005 #pragma / __declspec / otro?

p.s .: No puedo usar el compilador de C, porque mi código es parte (uno de los módulos de cientos) de la gran proyecto. Y ahora está en C ++. Yo sé, puedo construir mi código por separado. Pero es el código antiguo y sólo quiero al puerto rápido.

La pregunta se refiere a void * fundición;) Si no es posible, basta con sustituir MACRO_SAFE con MACRO_SAFE_CPP

Gracias!

¿Fue útil?

Solución

No recomiendo hacer esto; esto es terrible código y si está utilizando C se debe compilar con un compilador de C (o, en Visual C ++, como un archivo C)

Si está utilizando Visual C ++, puede utilizar decltype:

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

Otros consejos

A hace que la respuesta de James aún más sucio, si no tiene el apoyo decltype también se puede hacer esto:

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

A continuación:

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

I amplió esta utilidad (en C ++ 11) en mi blog . No lo use para otra cosa que el mal.

Por ejemplo, como este:

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

¿Hay alguna razón nadie sólo moldes var , su argumento para SAFE_MALOC ()? Es decir, malloc () devuelve un puntero. Usted está almacenando en alguna parte que acepta un puntero ... Hay todo tipo de cosas con seguridad de tipos ordenadas que otras personas ya han señalado ... me pregunto por qué esto no funcionó:

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

Sí ... lo sé. Es enfermos, y lanza la derecha tipo de seguridad por la ventana. Sin embargo, una recta ((void *) (var)) = Reparto haría no siempre funciona.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top