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

Суеверие: почему старожилы предпочитают GetFileAttributes для проверки существования файла?

Это перевод Superstition: Why is GetFileAttributes the way old-timers test file existence? Автор: Реймонд Чен.

Если вы спросите старого пердуна: "Как проверить наличие файла?", он наверняка ответит: "Используй GetFileAttributes". Это и сегодня, вероятно, самый быстрый способ проверки существования файла, поскольку он требует только одного вызова. Другие методы (такие как FindFirstFile или CreateFile) требуют дополнительного вызова FindClose или CloseHandle - что приведёт к дополнительным запросам по сети, увеличивая стоимость проверки.

Но в прежние времена выбор GetFileAttributes был не просто оптимизацией производительности. Если вместо этого вы попытаетесь открыть файл для проверки его существования, вы можете и вовсе получить неправильный ответ!

четверг, 5 сентября 2019 г.

Что такое __wchar_t (с двумя ведущими подчёркиваниями) и почему у меня вылезают связанные с ним ошибки?

Это перевод What is __wchar_t (with the leading double underscores) and why am I getting errors about it? Автор: Реймонд Чен.

Компилятор Microsoft Visual C++ имеет параметр компилятора с названием /Zc:wchar_t, который позволяет вам контролировать, что же означает тип wchar_t.

Согласно стандарту C++, wchar_t - это отдельный родной (встроенный, нативный) тип, и именно так по умолчанию считает компилятор Visual C++. Тем не менее, вы можете передать /Zc:wchar_t-, и это отключит встроенное определение типа wchar_t, позволяя вам определить тип так, как вам нравится. А для Windows это исторически означает:
typedef unsigned short wchar_t;
потому что Windows предшествует версиям стандартов C и C++, которые представили wchar_t как собственный тип.

Так что теперь у вас есть проблема, если вы пишете библиотеку, которая будет использоваться как кодом старой школы, написанным с wchar_t, определённым как псевдоним для unsigned short, так и кодом новой школы, написанным с wchar_t как отдельным внутренним типом. Какой тип данных вам нужно использовать для строковых параметров?

Печальная история спецификаторов форматирования в стиле printf в Visual C++

Это перевод The sad history of Unicode printf-style format specifiers in Visual C++. Автор: Реймонд Чен.

Windows реализовала Unicode раньше, чем большинство других операционных систем. В результате решения Windows для многих проблем отличаются от решений, принятых теми, кто подождал, когда пыль осядет¹. Самым ярким примером этого является использование Windows UCS-2 в качестве кодировки Unicode. Тогда это была кодировка, рекомендованная консорциумом Unicode, потому что Unicode 1.0 поддерживал только 65'536 символов². Консорциум Unicode передумал пять лет спустя, но к тому времени было уже слишком поздно для Windows, которая уже выпустила Win32s, Windows NT 3.1, Windows NT 3.5, Windows NT 3.51 и Windows 95 - все из которых использовали UCS-2³.

Но сегодня мы поговорим о строках формата в стиле printf.

Обновлено: Если FlushInstructionCache ничего не делает, почему я должен её вызывать?

Это перевод If FlushInstructionCache doesn’t do anything, why do you have to call it, revisited. Автор: Реймонд Чен.

Предполагается, что вы будете вызывать функцию FlushInstructionCache, когда вы генерируете или модифицируете исполняемый код в run-time - чтобы процессор при выполнении вашего сгенерированного/модифицированного кода читал бы написанные вами инструкции, а не старые инструкции, которые могут остаться в кеше команд процессора.

Ранее мы узнали, что в Windows 95 функция FlushInstructionCache не делает ничего, кроме возврата. Это потому, что простого вызова функции было достаточно, чтобы очистить кэш команд.

Но в Windows NT функция FlushInstructionCache выполняет реальную работу, поскольку ей необходимо уведомить все остальные процессоры о необходимости очищать их кэши.

Однако если вы посмотрите на Windows 10, то вы обнаружите, что функция FlushInstructionCache выглядит как версия для Windows 95: она ничего не делает.

В чём тут дело?