- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
program Project6;
{$APPTYPE CONSOLE}
uses SysUtils;
type TIntArr = array of integer;
function GetSingleArr (i: integer): TIntArr;
begin
SetLength(Result, 1);
Result[0] := i;
end;
var
W: TIntArr;
i : integer;
begin
readln(i);
if i=0 then begin
W := GetSingleArr(5);
WriteLn(W[0]);
end;
ReadLn;
end.
Delphi-7
[Warning] Project6.dpr(25): Variable 'W' might not have been initialized
Да какого хуя? Динмассив вообще по определению - чисто автоматический тип, как он может не инициализироваться?
И почему для других типов такая хрень не вылазит?
[email protected] (Спросить Тараса)
[email protected] (Спросить Тараса)
z.pas(21) Hint: Value assigned to 'i' never used
z.pas(20) Warning: Variable 'i' might not have been initialized
А у меня наоборот!
У меня ничего подобного не происходит - W я использую только в ветке, в которой я его явно инициализирую (в других он инициализируется неявно). Если я вместо TIntArr применю иной тип (например, String), то этого предупреждения не будет, вот что самое дурацкое.
P.S. На type TIntArr = array [0..9000] of integer; Дельфи не ругается. Ругается только на динамический.
Стринги всегда инициализируются компилятором, это не пример.
Такой пример наводит на какие-нибудь мысли, не?
или даже
Динмассивы тоже.
> Такой пример наводит на какие-нибудь мысли, не?
Не имеет никакого отношения, тут запись в хзкакой адрес.
Мой код 100% корректен.
Теперь сравни с предыдущим примером и пойми почему :)
Сравнил.
Ну, и почему же мой пример даёт предупреждение?
В любом случае код финализации массива одинаковый.
Этот код:
В чём разница, кроме вызова DynArrayAsg для копирования массива из безымянной переменной в стеке в W?
Это Object Pascal.
[email protected] (Спросить Тараса)
PS: Или будь уникален и линяй на Аду. Тоже есть чем нагибать.
Какого? Да и причем тут язык?
А еще, что вам мешает на Си реализовать контейнер паскалестрок?
А да еще, в этом ваши делфи освобождением памяти от строк(и от дин.массивов) занимается GC, что куда дороже, чем нультерминированная строка.
http://stackoverflow.com/questions/4440841/garbage-collection-in-delphi
По поводу данного кода: W может не инициализироваться, если цикл будет выполнен 0 раз, к этому выводу приходит компилятор, анализируя Control-Flow-Graph. Поэтому тут все в порядке.
2. За ссылку спасибо, посмотрю.
3. Если цикл будет выполнен 0 раз, то переменная использована будет тоже 0 раз.
Это не паскаль строки - это сишные строки, только с добавночной длинной. Т.е. сама длинна строки к строке не имеет отношения, она имеет отношение только к указателю.
В питух паскаль строке - сделанно как в маллоке. char * str; *(uint16_t *)str = len;
И да, самая быстрая конкатенация строк в сишке. Была и всегда будет.
Компилятору все равно, он всего лишь анализирует граф потока управления.
array of T в паскале - не более чем указатель.
Это указатель с автоматикой. И только на нём компилятор клинит в паранойю. На string - не клинит.
И сравнивать string и array of T некорректно, имхо.
А вот string^ и array of T уже можно, ибо и то и то - указатели.
Нихуя подобного, они оба инициализируюся нилом, учи матчасть.
[email protected] (Спросить Тараса)
Да откуда там GC!? Емнип, на строках только счетчик ссылок, только хардкор.
ARC часто рассматривают как частный случай GC;
GC вполне себе реализуется в языках с компиляцией в натив.
Однако, если бы было ARC, то при каждой циклической ссылке в объектах - происходила бы утечка памяти.
Не путай ГЦ и автодеструкторы, у них есть очень, очень важные отличия.
Откуда взяться циклическим ссылкам в строках? А для объектов там ARC и не работает.
> происходила бы утечка памяти
Проблема, на самом деле, довольно надуманная. А если есть weak_ptr и немного мозгов - ее вообще почти не существует.
А вот если в динмассив запечь RC-интерфейс с полем с таким динмасивом, то тут таки да, будут проблемы.
Если строки реализованы как "веревки" (ropes), то вполне может получиться, если тому, кто реализовывал захочется хранить указатели в обе стороны (от родителей к детям и обратно).
Какой нахуй GC?
> W может не инициализироваться, если цикл будет выполнен 0 раз
Где цикл? W нужна и используется только внутри одной ветки.
Что сука характерно, если вместо TIntArr взять любой другой тип, хоть string,похожий по принципу работы, то этого неуместного предупреждения не будет.
Ну и как вообще динмассив может не инициализироваться, если это автоматический тип?
Учи матчасть, он инициализируется нилом. Иначе бы при первой смене длины он попытался бы освободить старый мусор, пиздец же был бы, да?
> а string - аллоцируется автоматически.
Учи матчасть, нихуя он не аллоцируется, он инициализируется нилом.
struct{
int len;
char* str;
};
И соответственно при входе в процедуру выделяется память(чаще всего на стеке, если строка не возвращается) для длины и указателя.
Шел бы сам матчать учил.
PCHar конечно же устанавливается в nil, но мы же о обычных паскале строках.
Откуда ты знаешь? Это в крестах так, а в Дельфи - не так.
Ты ж нихуя не знаешь, только умными словами на английском языке кидаться горазд, лолка.
К твоему сведению, в Паскале строка выглядит так:
Дальше берётся что-то типа
Потом при SetLength вызывается аллокатор для NewLength+SizeOf(StrRec)
После чего возвращается указатель не тот, что вернул аллокатор, а P+SizeOf(StrRec), то есть строка - это указатель на первый символ, а перед ним идут ещё 8 байт структуры StrRec.
> но мы же о обычных паскале строках.
Обычные - это которые до 255 символов? Я не про них.
http://ideone.com/l58zHK
string[N] (точнее ShortString) — это struct { char len; char str[N]; }; Да, никаких указателей и никаких интов, только чар, только хардкор.
String без указания длины — это указатель на str[1].
array of char — это указатель на array [0..длина - 1] of char. Аналогично, AnsiString, WideString, UTF8String — такие же указатели на массив.
А ShortString — это struct { char len; char str[N]; }, как и string[N].
Если разыменовать AnsiString, WideString, UTF8String, то по смещению минус четыре перед массивом хранится его размер в байтах. А если разыменовать array of char, то перед массивом по смещению минус восемь хранятся два числа: диапазон его индексов (а по смещению минус двенадцать — вероятно, тип элементов).
var w: TIntarray;
begin
end;
если заменить на string, то варнинг пропадает. разница - в вызове _DynArrayClear или LStrClr.
Причем, аргумент, который указатель на строку/массив передавется одинаково.
Глюк компилятора, походу.
Но в таком коде хотя бы есть неиспользуемые переменные.
Я постарался подобрать код, который не должен вообще выдавать претензий.
кстати, если в начале добавить w := NIL, варнинг пропадает.
а разница вот в чем (модуль system):
procedure _LStrClr(var S);
procedure _DynArrayClear(var a: Pointer; typeInfo: Pointer);
Ну да, неявно вызываются разные функции, всё равно не понимаю. Один из них не помечена как "считать что переменная использована если вызывается"?
в любом случае - фигня какакя-то.