C-> C ++ Faça o ponteiro de vazio automaticamente no ponteiro de tipo em C ++ em #Define no caso de tipo não é dado (estilo C) [MSVS

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

Pergunta

Oi!

Eu usei o seguinte C macro, mas em C ++ não pode ser lançado automaticamente void* para type*.

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

Eu sei, eu posso fazer algo assim:

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

Mas não quero reescrever uma grande parte do código, onde MALLOC_SAFE foi usado.

Existe alguma maneira de fazer isso sem dar o tipo à macro? Talvez um pouco MSVC 2005 #pragma/__declspec/outro ?

PS: Não posso usar o C Compiler, porque meu código é parte (um dos centenas de módulos) do grande projeto. E agora está no C ++. Eu sei, posso construir meu código separadamente. Mas é um código antigo e eu só quero portá -lo rápido.

A questão é sobre void* fundindo;) Se não for possível, apenas substituirei o macro_safe por macro_safe_cpp

Obrigada!

Foi útil?

Solução

Eu não recomendo fazer isso; Este é um código terrível e, se você estiver usando C, você deve compilá -lo com um compilador C (ou, no visual c ++, como um arquivo C)

Se você estiver usando o Visual C ++, pode usar decltype:

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

Outras dicas

Tornar a resposta de James ainda mais suja, se você não tiver decltype Suporte você também pode fazer isso:

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

Então:

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

Eu expandi este utilitário (em C ++ 11) em meu blog. Não use para nada além do mal.

Por exemplo, 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; \
}

Existe uma razão pela qual ninguém apenas lança var, seu argumento para safe_maloc ()? Quero dizer, MALLOC () Retorna um ponteiro. Você está armazenando em algum lugar que aceita um ponteiro ... Existem todos os tipos de coisas legais que outras pessoas já apontaram ... Estou me perguntando por que isso não funcionou:

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

Sim, eu sei. Está doente e joga a segurança do tipo na janela. Mas um reto ((void *) (var)) = O elenco nem sempre funcionaria.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top