У меня такой вопрос: зачем Microsoft в WinApi создает свои макросы для имеющихс
в языке определений? Например CHAR == char, DOUBLE == double, LPCSTR == char* и так далее.
Ответы
Ответ 1
Все очень просто. На самом деле на все стандартные типа накладывается слишком мал
ограничений. Тот же char по факту может быть как знаковым, так и беззнаковым. Тот же double может иметь различную длину:
The type double provides at least as much precision as float, and the type long double provides at least as much precision as double.
То есть, точная длина в байтах неведома. Да, для конкретной реализации комплятора она известна, но в общем случае — нет.
А теперь представьте себе ситуацию, что есть много-много строк кода, и в один ден
разработчики компилятора сказали, что char у них будет беззнаковый (раньше мне така
ситуация показалась бы надуманной. Но теперь, когда ARM и MIPS процессоры прочно входят в нашу жизнь, когда 128 битные платформы не за горами, возможно и не такое). И что теперь делать? Перепроверять тонны кода? Гадать, почему на одной платформе работает, а на другой нет?
Поэтому и определяют свой тип, который имеет гарантированное поведение, а также понятное (легко для поиска и восприятия) и не очень длинное (сравните CHAR и signed char) название.
А вот с типами LPCSTR ситуация ещё интереснее. Помню, когда то давно, когда я тольк
начинал изучать си и плюсы, мне нужно было переписать небольшой код, который работа
с трехмерными массивами (для кафедры, где я учился). Передача по указателю, когда
тебя три звездочки подряд, запутывает окончательно. Но если объявить тип вида typedef int*** matrix;, то передача по ссылке значительно упрощается ( void func(matrix * data);) И не нужно думать, сколько там звездочек нужно поставить. От правильно составленной структуры типов продуктивность повышается в разы.
Ответ 2
Это касается почти любой API, в том же OpenGL и Direct3D свои переопределяемые типы
Даже в стандарт stddef/cstddef входят переопределяемые типы, такие как size_t, ptrdiff_t и т.д.
Вот простой пример: ты используешь арифметику указателей на 32-битной платформе
своём проекте, иногда храня указатель в типе int, после захочешь перенести свой проек
на 64-битную платформу, так вот данный тип int для хранения указателя может и не поместится из-за различия размерности void* (указателя) между int. Так вот, тебе придётся везде тип int изменить на 64-битный тип, а если бы ты сразу использовал ptrdiff_t, то не пришлось бы делать лишнюю работу.
В WinAPI есть аналоги типа INT_PTR/UINT_PTR, LONG_PTR/ULONG_PTR, DWORD_PTR...
То же самое касается типов, которые гарантированно дают размерность битности ка
UINT8 (1-байт), UINT16 (2-байта), UINT32 (4-байта), UINT64 (8-байт)...
p.s. даже такая истинность — не панацея: sizeof(int) == sizeof(__int32) может быть и истинно, а может быть и ложно.
Комментариев нет:
Отправить комментарий