В процессе разработки парсера синтаксиса Delphi была обнаружена интересная особенность в интерфейсе Winapi.ShellAPI. В отличие от большинства объявлений, некоторые строки, а именно объявления функций SHQueryRecycleBin, SHQueryRecycleBinA и SHQueryRecycleBinW, не заканчиваются точкой с запятой.
function SHLoadNonloadedIconOverlayIdentifiers; external shell32 name 'SHLoadNonloadedIconOverlayIdentifiers';
function SHQueryRecycleBin; external shell32 name 'SHQueryRecycleBinW'
function SHQueryRecycleBinA; external shell32 name 'SHQueryRecycleBinA'
function SHQueryRecycleBinW; external shell32 name 'SHQueryRecycleBinW'
function SHQueryUserNotificationState; external shell32 name 'SHQueryUserNotificationState' delayed;
Возникает вопрос: является ли это допустимым синтаксисом Delphi или же это просто ошибка в компиляторе?
Обсуждение и возможные объяснения
В сообществе Delphi нет единого мнения по этому поводу. Официального стандарта языка не существует, поэтому "правильным" считается то, что принимает компилятор. Однако, документация Delphi указывает, что все объявления должны завершаться точкой с запятой.
Возможные причины такого поведения:
Историческое наследие: Данная особенность могла возникнуть давно и сохраниться ради обратной совместимости. В старых версиях Delphi это могло быть допустимым синтаксисом, и изменение поведения компилятора могло бы сломать существующий код.
Особенность обработки external-функций: Компилятор может иначе обрабатывать объявления external-функций, позволяя опускать точку с запятой в определенных случаях.
Недокументированная особенность: Возможно, это просто недокументированная особенность языка, которая не является ни багом, ни фичей в явном виде.
Решение и альтернативы
Сообщить об ошибке: Наиболее правильным решением будет сообщить об этой особенности разработчикам Embarcadero (Emba). Они могут либо исправить код в Winapi.ShellAPI, добавив недостающие точки с запятой, либо объяснить причину такого поведения и, возможно, задокументировать его.
Принять как данность: Если компилятор не выдает ошибок, можно просто принять это как данность и продолжать использовать код как есть. Однако, это может привести к проблемам при использовании других парсеров или инструментов анализа кода, которые могут не поддерживать такой синтаксис.
Добавить точки с запятой самостоятельно: В качестве временного решения можно добавить недостающие точки с запятой в локальную копию Winapi.ShellAPI. Это позволит избежать проблем с парсерами и другими инструментами, но потребует повторения этой процедуры при каждом обновлении Delphi.
Альтернативное решение:
Вместо прямого изменения Winapi.ShellAPI, можно создать собственную обертку для этих функций, добавляя точки с запятой в объявления. Это позволит избежать изменения системных файлов и упростит поддержку кода при обновлениях Delphi.
unit MyShellAPI;
interface
uses
Winapi.ShellAPI;
function MySHQueryRecycleBin(pszRootPath: PChar; pSHRBStruct: PSHQUERYRBINFO): HResult; external shell32 name 'SHQueryRecycleBinW';
function MySHQueryRecycleBinA(pszRootPath: PChar; pSHRBStruct: PSHQUERYRBINFO): HResult; external shell32 name 'SHQueryRecycleBinA';
function MySHQueryRecycleBinW(pszRootPath: PChar; pSHRBStruct: PSHQUERYRBINFO): HResult; external shell32 name 'SHQueryRecycleBinW';
implementation
function MySHQueryRecycleBin(pszRootPath: PChar; pSHRBStruct: PSHQUERYRBINFO): HResult;
begin
Result := SHQueryRecycleBinW(pszRootPath, pSHRBStruct); // Используем оригинальную функцию
end;
function MySHQueryRecycleBinA(pszRootPath: PChar; pSHRBStruct: PSHQUERYRBINFO): HResult;
begin
Result := SHQueryRecycleBinA(pszRootPath, pSHRBStruct); // Используем оригинальную функцию
end;
function MySHQueryRecycleBinW(pszRootPath: PChar; pSHRBStruct: PSHQUERYRBINFO): HResult;
begin
Result := SHQueryRecycleBinW(pszRootPath, pSHRBStruct); // Используем оригинальную функцию
end;
end.
Этот код создает новый модуль MyShellAPI с функциями-обертками, которые вызывают оригинальные функции из Winapi.ShellAPI. В объявлении функций-оберток точки с запятой присутствуют.
Заключение
Отсутствие точки с запятой в объявлениях SHQueryRecycleBin и связанных с ней функций в Winapi.ShellAPI является интересной особенностью синтаксиса Delphi, которая требует дальнейшего исследования и, возможно, исправления со стороны разработчиков Embarcadero. В то же время, предложенные решения, такие как создание оберток, позволяют обойти эту проблему и обеспечить совместимость кода с различными инструментами анализа. Важно помнить, что в Pascal точка с запятой является разделителем операторов, а не терминатором, что объясняет, почему компилятор может не выдавать ошибку в данном случае.
В интерфейсе Winapi.ShellAPI обнаружена необычная особенность синтаксиса Delphi, заключающаяся в отсутствии точек с запятой в объявлениях некоторых WinAPI-функций, что вызывает вопросы о допустимости и возможных решениях для обеспечения совместимости код
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.