Почему большинство примеров Delphi использует FillChar () для инициализации записей?

Ну ... Это действительно большая тема, поэтому на нее трудно ответить, но есть лучшие практики, которым вы должны / могли бы следовать.

Сначала - Все основано на ВАШЕЙ КОНКРЕТНОЙ аудитории. Посмотрите на свою аналитику и посмотрите, какие браузеры используются. Эти данные могут вас удивить, особенно если вы пользуетесь услугами здравоохранения или государственных учреждений США. Такие инструменты, как Stylelint , помогут вам найти неподдерживаемые правила в вашем CSS.

Далее, рекомендуется использовать функцию обнаружения вместо нацеливания на определенные браузеры. Вы можете реализовать это, используя @supports в условном коде, который работает как media query. Таким образом, ваш код применяется только в том случае, если браузер может его использовать. Вы можете сделать подобное обнаружение в JavaScript, используя Modernizr .

Наконец, я лично рекомендую использовать постпроцессор CSS или скрипт сборки, чтобы вы могли перестать беспокоиться о префиксах (плюс это ускорит вашу разработку с помощью дополнительных плагинов). Мне нравится комбо из PostCSS и Prefixfree (несколько настроек Webpack поставляются с включенными), но есть много похожих вариантов.

Основным преимуществом является то, что библиотека отслеживает то, что требует префиксов, а что нет, поэтому вы пишете версию без префиксов, а обо всем остальном позаботятся.


Нет жестких и быстрых правил, но вы должны стараться поддерживать устройства своих пользователей, а не настаивать на обновлениях. Хорошая вещь в вышеупомянутых практиках состоит в том, что ваш результирующий код будет легче поддерживать, он будет ориентирован на будущее и предназначен для ваших пользователей.

28
задан menjaraz 15 March 2012 в 13:24
поделиться

5 ответов

Исторические причины, в основном. FillChar () восходит к дням Турбо Паскаля и использовался для таких целей. Название действительно немного неправильное, потому что, хотя оно говорит Fill Char (), на самом деле это Fill Byte (). Причина в том, что последний параметр может принимать символ или байт. Таким образом, FillChar (Foo, SizeOf (Foo), # 0) и FillChar (Foo, SizeOf (Foo), 0) эквивалентны. Еще одним источником путаницы является то, что по состоянию на Delphi 2009 FillChar по-прежнему заполняет только байты, хотя Char эквивалентен WideChar. Рассматривая наиболее распространенные варианты использования FillChar, чтобы определить, использует ли большинство людей FillChar для фактического заполнения памяти символьными данными или просто для инициализации памяти некоторым заданным байтовым значением, мы обнаружили, что это был последний случай, который доминировал над его использованием, а не первый. При этом мы решили сохранить байтово-центрированный FillChar.

Это правда, что очистка записи с помощью FillChar, которая содержит поле, объявленное с использованием одного из «управляемых» типов (строки, Variant, Interface, динамические массивы), может быть небезопасной, если не используется в правильном контексте. Однако в приведенном вами примере безопасно вызывать FillChar для локальной объявленной переменной записи , если это первое, что вы когда-либо делаете с записью в этой области . Причина в том, что компилятор сгенерировал код для инициализации строкового поля в записи. Это уже установит строковое поле в 0 (ноль). Вызов FillChar (Foo, SizeOf (Foo), 0) просто перезапишет всю запись 0 байтами, включая строковое поле, которое уже равно 0. Использование FillChar для переменной записи после значения было присвоено строковому полю, не рекомендуется. Использование вашей техники инициализированных констант является очень хорошим решением этой проблемы, потому что компилятор может сгенерировать правильный код, чтобы гарантировать, что существующие значения записи будут правильно завершены во время присваивания.

36
ответ дан 28 November 2019 в 02:41
поделиться

FillChar прекрасно подходит, чтобы убедиться, что вы не получите никакого мусора в новом неинициализированном структура (запись, буфер, массив ...).
Его не следует использовать для «сброса» значений, не зная, что вы сбрасываете.
Не более чем просто написать MyObject: = nil и ожидать избежать утечки памяти.
В частности, следует внимательно следить за всеми управляемыми типами.
См. Функцию Finalize .

Когда у вас есть возможность напрямую поиграть с памятью, всегда есть возможность выстрелить себе в ногу.

9
ответ дан 28 November 2019 в 02:41
поделиться

FillChar is usually used to fill Arrays or records with only numeric types and array. You are correct that it shouldn't be used to when there are strings (or any ref-counted variables) in the record.

Although your suggestion of using a const to initialize it would work, an issue comes into play when I have a variable length array that I want to initialize.

4
ответ дан 28 November 2019 в 02:41
поделиться

Traditionally, a character is a single byte (no longer true for Delphi 2009), so using fillchar with a #0 would initalize the memory allocated so that it only contained nulls, or byte 0, or bin 00000000.

You should instead use the ZeroMemory function for compatibility, which has the same calling parameters as the old fillchar.

2
ответ дан 28 November 2019 в 02:41
поделиться

Этот вопрос имеет более широкое значение, что был в моей голове целую вечность. Я тоже был воспитан на использовании FillChar для записей. Это хорошо, потому что мы часто добавляем новые поля в запись (data) и, конечно, FillChar (Rec, SizeOf (Rec), # 0) заботится о таких новых полях. Если мы «сделаем это правильно», нам придется перебирать все поля записи, некоторые из которых являются перечисляемыми типами, некоторые из которых могут быть самими записями, а полученный код будет менее читабельным, а также, возможно, ошибочным, если мы не добавим new записывать поля к нему прилежно. Строковые поля являются общими, поэтому FillChar теперь нет-нет. Несколько месяцев спустя,

1
ответ дан 28 November 2019 в 02:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: