В реализации Visual Studio для type_info, обычно расположенного в C: \ Program Files (x86) \ Microsoft Visual Studio 10.0 \ VC \ include \ typeinfo:
class type_info {
/* ... */
_CRTIMP_PURE bool __CLR_OR_THIS_CALL operator==(const type_info& _Rhs) const;
/* ... */
private:
void *_M_data;
char _M_d_name[1];
__CLR_OR_THIS_CALL type_info(const type_info& _Rhs);
/* ... */
};
Я заметил, что реализация оператора равенства == использует символьный указатель _M_d_name + 1. Может кто-нибудь объяснить мне, как это «работает», потому что кажется, что оно выходит за границы массива?
Реализация, C: \ Program Files (x86) \ Microsoft Visual Studio 10.0 \ VC \ crt \ src \ ti_inst.cpp:
ASSERT_UNMANAGED_CODE_ATTRIBUTE
SECURITYSAFECRITICAL_ATTRIBUTE
bool type_info::operator==(const type_info& rhs) const
{
return (strcmp((rhs._M_d_name)+1, (_M_d_name)+1)?0:1);
}
Спасибо!
Этот трюк для гибкого члена массива. Это выделит память для class type_info
и имя строки, так (rhs._M_d_name)+1
именно там, где находится строка имени. Вот диаграмма, чтобы описать это:
+------------+ --+
| | |
+------------+
| | |
| | ->type_info
+------------+ |
+-------+ _M_d_name | |
| +------------+ --+
+-------> |
| |
| |
+------------+
На самом деле, C99 поддерживает эту функцию и расширение Microsoft позволяет последнему члену структуры или класса C или C ++ быть массивом переменного размера