C->C++ 型が指定されていない場合、#define で C++ の Type ポインターに void ポインターを自動的にキャストします (C スタイル) [MSVS]

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

質問

こんにちは!

私は以下を使用しました C マクロ、しかし C++ 自動的にキャストできない void*type*.

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

わかっています、次のようなことができます。

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

しかし、コードの大部分を書き直すつもりはありません。 MALLOC_SAFE 使われた。

マクロに型を与えずにこれを行う方法はありますか?たぶん、いくつか MSVC 2005 #pragma/__declspec/他の ?

追記:私のコードは大規模プロジェクトの一部 (数百のモジュールの 1 つ) であるため、C コンパイラーは使用できません。そして今は C++ 上です。コードを個別にビルドできることはわかっています。しかし、これは古いコードなので、すぐに移植したいだけです。

質問は void* キャストに関するものです ;) それが不可能な場合は、MACRO_SAFE を MACRO_SAFE_CPP に置き換えます。

ありがとう!

役に立ちましたか?

解決

これを行うことはお勧めしません。これはひどいコードなので、C を使用している場合は、C コンパイラで (または、Visual C++ では C ファイルとして) コンパイルする必要があります。

Visual C++ を使用している場合は、次を使用できます。 decltype:

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

他のヒント

あなたが持っていない場合、ジェームズの答えはさらに汚くなります 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);
}

それから:

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

このユーティリティ(C++11)を拡張しました 私のブログ. 。悪事以外には使用しないでください。

たとえば、次のようになります。

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

誰もキャストしない理由はありますか 変数, 、SAFE_MALOC() に対する引数は?つまり、 malloc() ポインタを返します。ポインタを受け入れる場所に保存しています...他の人がすでに指摘しているように、あらゆる種類のきちんとしたタイプセーフなものがあります...なぜこれがうまくいかなかったのか疑問に思っています:

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

うん...知っている。それは病気であり、タイプセーフティを窓の外に放り出します。でもストレート ((void *)(var))= キャストは常に機能するとは限りません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top