9

やあ!

次の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/other ?

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

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

ありがとう!

4

4 に答える 4

36

ジェームズの答えをさらに汚いものにするために、サポートがない場合は、次の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) については、ブログで詳しく説明しています。悪事以外には使わないでください。

于 2010-10-26T20:31:31.480 に答える
15

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

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

#define MALLOC_SAFE(var, size)                      \
{                                                   \
    var = static_cast<decltype(var)>(malloc(size)); \
    if (!var) goto error;                           \
}
于 2010-10-26T20:24:54.553 に答える
5

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

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; \
}
于 2010-10-26T20:58:37.403 に答える
4

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

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

ええ...知っています。それは病気であり、型安全性を窓の外に投げ出します。しかし、単純な((void *)(var))=キャストは常に機能するとは限りません。

于 2010-10-26T21:21:58.127 に答える