次の宣言は、C++ファイルでコンパイルするための演算子をいくつか追加します。定義は、CファイルとC++ファイルの両方に含まれています。
PC-Lintがエラー114を報告しています:タグ'Rect'の構造宣言に一貫性がありませんが、安全であると確信しています。
VisualStudio2008でコンパイルしています。
編集-クライアントに送信した説明を追加します
Rectの問題に関して; 構造体がCとC++で同じサイズであることを知ることで、「未定義動作」の疑いをどのように排除できますか。
データ構造内のフィールドの実際の場所がコンパイルによって異なる場合、未定義の動作が発生します。
すべてのメンバー変数アクセスは、最終的にはポインターに解決されると考える必要があります。これは、オブジェクトストレージの先頭へのポインターと、その構造内にあるものに応じたオフセットによって計算されます。
パッキングとデータアライメントの設定は、オフセットの値に影響します。
コンパイラーは、最適なアクセスのために型を並べ替えることができます。指定された順序で2つのメンバーを宣言したからといって、実際にはその順序で格納されていると想定するのは未定義の動作です。宣言順序が保証するのは、初期化、コピー、および破棄の順序だけです。
ただし、同じコンパイラ内で同じオフセット設定を使用して特定の構造体をCおよびC ++でコンパイルする場合、実際の並べ替えの可能性は事実上ゼロです。
したがって、心配する必要があるのは、フィールドのオフセットの違いだけです。
単純な4つの短整数を含む構造体の場合、CバージョンとC ++バージョンが同じサイズであることを確認するだけで、それらのオフセットがすべて同じであることが保証されます。さらに注意するために、構造体のサイズ= 4 * sizeof(short)であることを確認することもできます。
これらのチェックを追加する価値があると思いますが、一度追加すると、CとC ++で別々の型を使用する(または使用されている関数を無料の関数に移動する)ために必要なコードをリファクタリングする必要はありません。
/**
Mac-compatible rectangle type with some operators added for C++ use.
@ingroup QuickdrawPort
*/
struct Rect {
short top;
short left;
short bottom;
short right;
#ifdef __cplusplus
Rect(short _top=0, short _left=0, short _bottom=0, short _right=0) :
top(_top),
left(_left),
bottom(_bottom),
right(_right)
{}
#ifdef _WINNT_ // WinDef.h has been included
const Rect& operator=(const tagRECT& rhs) {
top = short(rhs.top);
left = short(rhs.left);
bottom = short(rhs.bottom);
right = short(rhs.right);
return *this;
}
operator tagRECT() const {
tagRECT lhs;
lhs.top = top;
lhs.left = left;
lhs.bottom = bottom;
lhs.right = right;
return lhs;
}
#endif// _WINNT_
short height() const { return bottom - top; }
short width() const { return right - left; }
bool empty() const { return right==left || bottom==top; }
bool operator==(const Rect& rhs) const {
return top == rhs.top &&
left == rhs.left &&
bottom == rhs.bottom &&
right == rhs.right;
}
#endif
};
#ifndef __cplusplus
typedef struct Rect Rect;
#endif