Следующее объявление добавляет пару операторов для компиляции в файл C ++.Определение включено в файлы C и C ++.
PC-Lint сообщает Ошибка 114: Несогласованное объявление структуры для тега 'Rect' , но я уверен, что это безопасно.
Я компилирую с Visual Studio 2008.
edit - добавление объяснения, которое я отправил своему клиенту
ОтносительноПрямой вопрос;как знание того, что структура имеет одинаковый размер в C и C ++, устраняет подозрение на «неопределенное поведение».
Неопределенное поведение возникает, если фактическое расположение полей в структуре данных меняется в зависимости от компиляции.
Вы должны думать о том, что доступ ко всем переменным-членам в конечном итоге разрешается указателю, вычисляемому указателем на начало хранилища объекта плюс смещение в зависимости от того, что находится в этой структуре.
Параметры упаковки и выравнивания данных влияют на значение смещения.
Компилятору разрешено переупорядочивать типы для оптимального доступа - это неопределенное поведение, предполагать, что только потому, что вы объявили два члена в заданном порядке, онина самом деле хранятся в этом порядке.Единственное, что гарантирует порядок объявления, - это порядок инициализации, копирования и уничтожения.
Однако, когда вы говорите о компиляции C и C ++ данной структуры в одном и том же компиляторе с одинаковыми настройками смещения, вероятностьфактическое переупорядочение фактически равно нулю.
Таким образом, единственное, что нам нужно беспокоиться, это любая разница в смещении полей.
Для структуры, содержащей простые 4 коротких целых числа, просто подтверждая, что CВерсия и версия C ++ имеют одинаковый размер, что гарантирует, что их смещения одинаковы.Чтобы быть более внимательным, мы также можем проверить, что структура size = 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