Страницы

Поиск по вопросам

понедельник, 25 ноября 2019 г.

Зачем Microsoft в WinApi создает свои макросы для имеющихся в языке определений?


У меня такой вопрос: зачем 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) может быть и истинно, а может быть и ложно.

Комментариев нет:

Отправить комментарий