6

C では、 へのポインタのキャストと からのポインタのキャストはエラーではありませんvoid *

C++ への移植における大きな障害は、 などの汎用ポインターを扱う関数mallocや、 などの独自のコードで宣言された関数から戻るときに、ポインターをキャストする必要があることvoid *block_get(Blkno const blkno);です。

ただし、私のコードは、CおよびC++ コンパイラによって正常にコンパイルされることを意図しています。C++ のためにどこでも明示的なキャストを提供する場合、それらは C スタイルのキャストである必要があり、両方の言語のポインター型との間で非ポインター型をキャストするため、バグをマスクしている可能性があります。

私の参照エラーは次のとおりです。

struct Cpfs *cpfs = calloc(1, sizeof(*cpfs));

MSVCで生成されるもの:

エラー 2 エラー C2440: 'initializing' : 'void *' から 'Cpfs *' に変換できません e:\src\cpfs\cpfs.c 179

明らかに私は使用できないnewstatic_cast、C を使用しなくなった場合に自然に使用するものです。最小限の冗長性で各言語を囲む最大の型安全性を提供する最良の方法は何ですか?void *

4

5 に答える 5

5

単純に C スタイルのキャストを使用するか、(C では) 何も展開しないマクロでキャストをラップするか、static_castC++ ではキャストをラップすることをお勧めします。

于 2010-10-03T09:39:54.113 に答える
2

コンパイラが をサポートしている場合はdecltype()、いくつかのマクロ マジックを使用して、型名を明示的に繰り返す必要がないようにすることができます (および、sizeof要素サイズのおかげで)。

#ifdef __cplusplus
#define my_calloc(VAR, COUNT) \
    static_cast<decltype(VAR)>(std::calloc(COUNT, sizeof *VAR))
#else
#define my_calloc(VAR, COUNT) calloc(COUNT, sizeof *VAR)
#endif

使用例:

#ifdef __cplusplus
#include <cstdlib>
#else
#include <stdlib.h>
#endif

struct Cpfs *cpfs = my_calloc(cpfs, 42);

ただし、よりクリーンなソリューションは、おそらく C コンパイラを使用してオブジェクト ファイルをリンクすることです...

于 2010-10-03T10:47:41.343 に答える
1

C および C++ ビルド用に異なる方法で定義できる置換アロケーター関数を作成します:- ヘッダー ファイルで次のようなもの:

#ifdef __cplusplus
template<typename TypeT>
TypeT* MyAlloc(TypeT** pOut,size_t cb){
  *pOut = static_cast<TypeT*>(malloc(cb)); //aint c++ pretty.
  return *pOut;
}
#else
  extern void* MyAlloc(void** ppv, size_t cb);
#endif

これで、C++ ビルドでは、処理対象の型を推測できる関数があり、C ビルドでは、void* を返す通常の関数があります。

唯一の問題は、割り当てるポインターを渡す必要があることです。C++ コンパイラーは、関数の戻り値の型のみに基づいてテンプレート パラメーターを推測しようとしません。したがって、次のように不可知論的に呼び出すことができます:-

int *p;
if(MyAlloc(&p,sizeof(int)*n)){
  ...
于 2010-10-03T09:53:41.360 に答える
0

私が知っている唯一の解決策は、明示的なキャストを行うことです。

struct Cpfs *cpfs = (Cpfs*)calloc(1, sizeof(*cpfs));

ここでは、両方のコンパイラが満足しています。また、古いコンパイラでは malloc が char* を返す場合があることも覚えておいてください。

h番目

マリオ

于 2010-10-03T09:43:07.933 に答える
0

たぶん、このようなものですか?(テストされていない、コンパイラが利用できない、マクロを頻繁に使用していない):

#ifdef __cplusplus
    #define pointer_cast(type, pointer) reinterpret_cast<type>(pointer)
#else
    #define pointer_cast(type, pointer) (type)(pointer)
#endif
于 2010-10-03T09:53:29.453 に答える