C->C++ 型が指定されていない場合、#define で C++ の Type ポインターに void ポインターを自動的にキャストします (C スタイル) [MSVS]
-
26-09-2019 - |
質問
こんにちは!
私は以下を使用しました 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))= キャストは常に機能するとは限りません。