C-> C ++ lanciato automaticamente puntatore nullo nel tipo puntatore in C ++ in #define in caso di tipo non sia presente (C-style) [MSVS]

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

Domanda

Hi!

Ho usato il seguente C macro, ma in C ++ non può lanciare automaticamente void* a type*.

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

Lo so, posso fare qualcosa di simile:

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

Ma io non voglio riscrivere una grande porzione di codice, in cui è stato utilizzato MALLOC_SAFE.

Esiste un modo per fare questo senza dare il tipo alla macro? Forse alcuni MSVC 2005 #pragma / __declspec / altro?

P.S .: Non posso usare il compilatore C, perché il mio codice fa parte (uno dei moduli centinaia) del grande progetto. E ora è il C ++. Lo so, posso costruire il mio codice separatamente. Ma è vecchio codice e voglio solo alla porta in fretta.

La domanda è di circa void * colata;) Se non è possibile, mi limiterò a sostituire MACRO_SAFE con MACRO_SAFE_CPP

Grazie!

È stato utile?

Soluzione

Non consiglio di fare questo; questo è terribile codice e se si utilizza C si deve compilarlo con un compilatore C (o, in Visual C ++, come un file C)

Se si utilizza Visual C ++, è possibile utilizzare decltype:

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

Altri suggerimenti

Per rende risposta James' ancora più sporco, se non si dispone di supporto decltype si può anche fare questo:

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

Quindi:

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

I ampliato su questa utilità (in C ++ 11) sul mio blog . Non usarlo per qualsiasi cosa, ma il male.

Ad esempio, in questo modo:

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

C'è un motivo nessuno solo calchi var , il tuo argomento di SAFE_MALOC ()? Voglio dire, malloc () restituisce un puntatore. Stai riporlo da qualche parte che accetta un puntatore ... Ci sono tutti i tipi di cose type-safe pulito che altre persone hanno già fatto notare ... Mi chiedo solo perché questo non ha funzionato:

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

Sì ... lo so. E 'malato, e lancia a destra tipo di sicurezza fuori dalla finestra. Ma un dritto ((void *) (var)) = Cast non sarebbe sempre il lavoro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top