.L3:
movslq %esi, %rdx /* sign extend counter<%esi> to 64bit %rdx */
addl (%rdi,%rdx,4), %eax /* res<%eax> += b<%rdi>[counter<%rdx>]; */
subl $1, %esi /* counter<%esi> -= 1 */
.L2:
testl %esi, %esi /* do counter<%esi> & counter<%esi> */
jns .L3 /* if result is no 0, jump to L3 */
В основном addl (%rdi,%rdx,4), %eax
- это доступ к массиву (%rdi
) с индексом счетчика (%rdx
) и добавление значения элемента в res (%eax
), 4
это просто умножение счетчика (%rdx
) для доступа к памяти, поскольку каждый адрес в массиве int
потребляет 4 байта в памяти вашей системы.
Строка в основном говорит: res += MEMORY[addrssOf(b) + counter*4]
Кстати, я думаю, вы хотите проверить, что size > 0
перед строкой int counter = size-1;
, а также, как P__J__
упоминается в его ответе, ваш res
может переполнение, поскольку оно имеет одинаковый тип каждого элемента в массиве, который вы суммируете.
Самая большая опасность с, за пределами патологических состояний как "с A, B, C, D" состоит в том, что Ваш код может тихо изменить значение без уведомления Вам. Рассмотрите этот пример:
with TFoo.Create
try
Bar := Baz;
DoSomething();
finally
Free;
end;
Вы пишете этот код, зная, что Панель является свойством TFoo, и Baz является свойством типа, содержащего метод, который имеет этот код.
Теперь, два года спустя, некоторый действующий из лучших побуждений разработчик входит, добавляет свойство Baz к TFoo. Ваш код тихо изменил значение. Компилятор не будет жаловаться, но код теперь взломан.
с [1 115] ключевое слово является хорошей функцией того, чтобы сделать Ваш код более читаемым, но существуют некоторые ловушки.
Отладка:
При использовании кода как это:
with TMyClass.Create do
try
Add('foo');
finally
Free;
end;
нет никакого способа осмотреть свойства этого класса, поэтому всегда объявлять переменную и использовать с [1 117] ключевое слово на этом.
Интерфейсы:
При создании интерфейса в с [1 119] пункт это живет до конца метода:
procedure MemoryHog;
begin
with GetInterfaceThatTakes50MBOfMemory do
Whatever;
ShowMessage('I''m still using 50MB of memory!');
end;
Ясность
При использовании класса в с [1 121] пункт, который имеет свойства или имена методов, который уже существует в объеме, он может одурачить Вас легко.
with TMyForm.Create do
Width := Width + 2; //which width in this with is width?
, Конечно, при наличии двойных названий, Вы используете свойства и методы класса, объявленного в Вашем с оператором (TMyForm).
with
оператор имеет свое место, но я должен согласиться, что злоупотребление может привести к неоднозначному коду. Хорошее эмпирическое правило состоит в том, чтобы удостовериться, что код более читаем и удобен в сопровождении после добавления с оператором. Если Вы чувствуете, что необходимо добавить комментарии для объяснения кода после добавления оператора затем, это - вероятно, плохая идея. Если код более читаем, поскольку в Вашем примере затем используют его.
btw: это всегда было одним из моих любимых шаблонов в Delphi для показа модального окна
with TForm.Create(nil) do
try
ShowModal;
finally
Free;
end
Я склоняюсь к отравлению с оператором в целом. Как ранее указано, это может сделать вещи сложными, и мой опыт состоит в том, что это будет. Много раз отладчик хочет, оценивают значения из-за withs, и все часто я нахожу вложенные withs, которые ведут для кодирования этого трудно для чтения.
код Brian кажется читаемым и хорошим, но код был бы короче, если Вы просто преобразовываете тип отправителя непосредственно, и Вы удаляете все сомнение относительно того компонента, который Вы включаете:
TAction(Sender).Enabled := Something;
, Если Вы обеспокоены вводом к очень, я предварительно тарифицирую для создания временной ссылки на длинный именованный объект:
var
t: TTable;
begin
t := theLongNamedDataModule.WithItsLongNamedTable;
t.FieldByName(' ');
end;
я не могу se, почему ввод должен побеспокоить Вас, все же. Мы - Машинистки Сначала, Программисты, Вторые , и завершение кода, вставка копии и запись ключа могут помочь Вам быть более эффективной машинисткой.
обновление: Просто споткнувшийся длинная статья с небольшим разделом по с операторами: он с ключевым словом. Самое отвратительное, опасное, blow-your-own-feet-off функция на языке. :-)
Когда я сначала начал программирование Паскаля (с TurboPascal!) и изученный, когда я пошел С замечательным казавшимся. Как Вы говорите, ответ на утомительный ввод и идеал для тех длинных записей. Так как Delphi прибыл, я удалял его и поощрял другой отбрасывать его - аккуратно суммированный Verity в регистр Кроме сокращения удобочитаемости существует две главных причины, почему я избежал бы его:
Тем не менее для удобочитаемости я все еще использую синтаксис:
procedure ActionOnUpdate( Sender : TObject )
begin
With Sender as TAction do
Enabled := Something
end;
я не видел лучшую конструкцию.
Вашим примером, datamodule доступа в рамках нажатия кнопки, является плохо изобретенный пример, по-моему. Целая потребность в С уходит при перемещении этого кода в модуль данных, где это должно быть. OnClick затем просто называет LongNameDataModule. InsertStuff и существует не с необходимым.
С плохое устройство, и необходимо посмотреть код для наблюдения, почему Вам нужен он. Вы, вероятно, сделали что-то не так или могли сделать это лучший путь.
Я - твердый сторонник удаления С поддержкой в Delphi. Ваше использование в качестве примера использования datamodule с именованными полями о единственном экземпляре, который я видел, что он разработал. Иначе лучший аргумент против него был дан Craig Stuntz - который я проголосовал.
я точно так же, как, чтобы указать, что со временем Вы можете в конечном счете (должен) rmeove, который все кодирование в событиях OnClick и Вашем коде также в конечном счете переместит далеко от именованных полей на datamodules в использование классов, которые переносят эти данные, и причина использовать С уйдет.
Основная проблема с "с" состоит в том, что Вы не знаете, где ее объем заканчивается, и у Вас могли быть несколько накладывающиеся с операторами.
я не думаю, что необходимо избегать использования его, пока код читаем.
Одно из предложений сделать это более читаемый (и менее сбивающий с толку в более длинном коде) было, если codegear добавил опция допускать псевдонимы в с, и вероятно позволяющий несколько withs в одном:
procedure TMyForm.AddButtonClick(Sender: TObject);
begin
with LongNameDataModule as dm, dm.LongNameTable1 as t1, dm.LongNameTable2 as t2 do
begin
t1.Insert;
t1.FieldByName('Field1').AsString := 'some value';
t1.FieldByName('Field2').AsString := t2.FieldByName('Field2').AsString;
t1.Post;
dm.Connection.Commit;
end
end;
Что касается меня, С довольно приемлемо в случае, который Вы даете. Это, конечно, улучшает ясность кода.
реальное зло - когда у Вас есть несколько with's, открытый сразу.
кроме того, мое мнение - то, что то, с чем Вы используете на, имеет большое значение. Если это - действительно другой объект затем с, вероятно, плохая идея. Однако мне не нравится иметь много переменных на одном уровне, даже когда это имеет смысл - обычно объекты данных, которые содержат весь очень сложный элемент данных - обычно вся обрабатываемая деталь, с которой программа разработана для работы. (Я не думаю, что этот случай произошел бы в приложении, которое не имело такого объекта.) Для создания мира более ясным, я часто использую записи на связанные с группой объекты. Я нахожу, что почти все withs, которые я использую, для доступа к таким подгруппам.
Существует много превосходных ответов здесь относительно того, почему с оператором плохо, таким образом, я попытаюсь не повторить их. Я использовал с оператором в течение многих лет, и я очень начинаю уклоняться от него. Это частично beause, может быть трудно разработать объем, но я начинал входить в рефакторинг в последнее время, и ни один из автоматизированных рефакторингов не работает скручивание жгутов с оператором - и автоматизировал рефакторинг, является потрясающим.
Также некоторое время назад я сделал видео на том, почему с оператором плохо, это не одна из моих лучших работ, но Здесь это
Ваш вопрос является отличным примером того, что «молоток - это не всегда решение».
В этом случае «с» не является вашим решением: вы должны вывести эту бизнес-логику из Ваша форма в вашем модуле данных. Это не нарушает Закон Деметры , как mghie (Майкл Хике), который уже прокомментировал.
Возможно, ваш пример был просто иллюстративным, но если вы на самом деле используете такой код в своих проектах вот что вы должны сделать вместо этого:
procedure TLongNameDataModule.AddToLongNameTable1(const NewField1Value: string);
begin
LongNameTable1.Insert;
LongNameTable1_Field1.Value := NewField1Value;
LongNameTable1_Field2.Value := LongNameTable2_LongNameField1.Value;
LongNameTable1_Field3.Value := LongNameTable3_LongNameField1.Value;
LongNameTable1_Field4.Value := LongNameTable4_LongNameField1.Value;
LongNameTable1.Post;
end;
И затем вызвать его из своей формы следующим образом:
procedure TMyForm.AddButtonClick(Sender: TObject);
begin
LongNameDataModule.AddToLongNameTable1('some value');
end;
Это эффективно избавляет вас от оператора with и делает ваш код более легким в обслуживании.
курс, заключающий строки Delphi в одинарные кавычки, также поможет компилировать их; -)