以下声明添加了几个用于在 C++ 文件中编译的运算符。该定义包含在 C 和 C++ 文件中。
PC-Lint 报告错误 114:标签“矩形”的结构声明不一致,但我确信它是安全的。
我正在使用 Visual Studio 2008 进行编译。
编辑 - 添加我发送给客户的解释
关于 Rect 问题;知道结构在 C 和 C++ 中的大小相同如何消除对“未定义行为”的怀疑。
如果数据结构中字段的实际位置因编译而异,则会发生未定义的行为。
您必须将所有成员变量访问视为最终解析为指针,该指针由指向对象存储开头的指针加上偏移量计算,具体取决于该结构中的内容。
打包和数据对齐设置会影响偏移值。
允许编译器重新排序类型以获得最佳访问 - 假设仅仅因为您以给定顺序声明了两个成员,它们实际上是按该顺序存储的,这是未定义的行为。声明顺序唯一保证的是初始化、复制和销毁顺序。
但是,当您在同一编译器中讨论给定结构的 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