Я подозреваю 64биный компилятор имеет небольшое количество смарт встроенные, чтобы позволить ему признать, что
- переменные инициализируются и не трогали, пока цикл не вводятся.
- Условие петли сравнивает переменную с литералом.
- начальное значение 0 удовлетворяет условию цикла, тем самым гарантируя, что цикл будет выполняться хотя бы один раз во время выполнения, эффективно делая его действующим как цикл
repeat..until
.
Поскольку компилятор все еще должен генерировать код для инициализации, но знает, что начальное значение не требуется во время выполнения, чтобы ввести цикл, оно может выдать предупреждение о том, что начальное значение будет не использовано.
Если вы не инициализируете переменную, компилятор не знает во время компиляции, будет ли введен цикл или нет, поскольку поведение не определено, поэтому компилятор выдает другое предупреждение о неинициализации переменной.
Просмотр разборки, вы можете увидеть, что петля превращается в repeat..until
петли и Prf := 0;
присваивания устранено путем оптимизации:
Project87.dpr.17: Result := 0;
00000000004261AA 4833D2 xor rdx,rdx
Project87.dpr.18: if Prefixes = 0 then
00000000004261AD 6685C0 test ax,ax
00000000004261B0 7460 jz GetPrefixesCount + $72
Project87.dpr.22: i := 0;
00000000004261B2 4D33C0 xor r8,r8
Project87.dpr.23: Prefixes := Prefixes and not Prf_VEX;
00000000004261B5 0FB7C0 movzx eax,ax
00000000004261B8 81E02DFBFFFF and eax,$fffffb2d
00000000004261BE 81F8FFFF0000 cmp eax,$0000ffff
00000000004261C4 7605 jbe GetPrefixesCount + $2B
00000000004261C6 E8050FFEFF call @BoundErr
Project87.dpr.26: Prf := (1 shl i);
00000000004261CB 41C7C101000000 mov r9d,$00000001
00000000004261D2 418BC8 mov ecx,r8d
00000000004261D5 41D3E1 shl r9d,r9b
00000000004261D8 4489C9 mov ecx,r9d
00000000004261DB 81F9FFFF0000 cmp ecx,$0000ffff
00000000004261E1 7605 jbe GetPrefixesCount + $48
00000000004261E3 E8E80EFEFF call @BoundErr
Project87.dpr.27: if (Prf and Prefixes = Prf) then
00000000004261E8 448BC9 mov r9d,ecx
00000000004261EB 664423C8 and r9w,ax
00000000004261EF 66443BC9 cmp r9w,cx
00000000004261F3 750A jnz GetPrefixesCount + $5F
Project87.dpr.28: Inc(Result);
00000000004261F5 80C201 add dl,$01
00000000004261F8 7305 jnb GetPrefixesCount + $5F
00000000004261FA E8F10EFEFF call @IntOver
Project87.dpr.29: Inc(i);
00000000004261FF 4180C001 add r8b,$01
0000000000426203 7305 jnb GetPrefixesCount + $6A
0000000000426205 E8E60EFEFF call @IntOver
Project87.dpr.24: while Prf < $8000 do
000000000042620A 6681F90080 cmp cx,$8000
000000000042620F 72BA jb GetPrefixesCount + $2B
Мое решение состоит в том, чтобы добавить это в начало устройства: {$ IFDEF WIN64} {$ HINTS OFF} // dcc64 дает недопустимые подсказки в этом устройстве. {$ ENDIF} –
@DavidHeffernan «Я не думаю, что Embarcadero обычно использует компилятор с подсказками и предупреждениями, потому что их библиотечный код полон подсказок и предупреждений». Вы перекомпилируете RTL/VCL/... или что заставляет вас так думать? –
@StefanGlienke Я перекомпилирую несколько единиц VCL для устранения некоторых дефектов. Во всех них есть предупреждения и подсказки. Включение переменной объявляется, но никогда не используется, а целая куча условно устаревших предупреждений. Я все еще на XE7. Возможно, они подтянулись. –