![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
$R- в созданном юните, непашет на уровне компиляции [D7, WinXP]
imm © (2006-02-09 23:22:00)Создаю новый юнит, пихаю туда
{$R-} //Убираем проверку индекса
type
TDArray = array[0..0] of Integer;
PDArray = ^TDArray;
implementation
procedure Hello;
var
t: PDArray;
begin
...
//Выделяем память
GetMem(t, SizeOf(Integer)*10);
//А здесь ошибка на этапе компиляции
t^[5] := 10;
...
end;
Как это исправить, то есть как это откомпилировать???? Помогите пожалуйста. За раннее вам благодарен.
han_malign (2006-02-13 10:37:00) [1]
> что в Delphi нельзя описать массив нулевой длины
- ну, допустим, в С++ это, нынче, тоже нерекомендумемая конструкция - warning выдает...
И приходится делать явно:
PData pData = (PData)(pRecord +1);
а смещение следующей записи, по любому, исподподвыподверта надо вычислять
pRecordNext = (PRecord)((PBYTE)pRecord + pRecord.cbSize);
Alex Konshin (2006-02-13 08:20:00) [2]Оттуда же еще пример:
PTypeData = ^TTypeData;
TTypeData = packed record
case TTypeKind of
tkUnknown, tkLString, tkWString, tkVariant: ();
tkInteger, tkChar, tkEnumeration, tkSet, tkWChar: (
OrdType: TOrdType;
case TTypeKind of
tkInteger, tkChar, tkEnumeration, tkWChar: (
MinValue: Longint;
MaxValue: Longint;
case TTypeKind of
tkInteger, tkChar, tkWChar: ();
tkEnumeration: (
BaseType: PPTypeInfo;
NameList: ShortStringBase;
EnumUnitName: ShortStringBase));
tkSet: (
CompType: PPTypeInfo));
tkFloat: (
FloatType: TFloatType);
tkString: (
MaxLength: Byte);
tkClass: (
ClassType: TClass;
ParentInfo: PPTypeInfo;
PropCount: SmallInt;
UnitName: ShortStringBase;
{PropData: TPropData});
tkMethod: (
MethodKind: TMethodKind;
ParamCount: Byte;
ParamList: array[0..1023] of Char
{ParamList: array[1..ParamCount] of
record
Flags: TParamFlags;
ParamName: ShortString;
TypeName: ShortString;
end;
ResultType: ShortString});
tkInterface: (
IntfParent : PPTypeInfo; { ancestor }
IntfFlags : TIntfFlagsBase;
Guid : TGUID;
IntfUnit : ShortStringBase;
{PropData: TPropData});
tkInt64: (
MinInt64Value, MaxInt64Value: Int64);
tkDynArray: (
elSize: Longint;
elType: PPTypeInfo; // nil if type does not require cleanup
varType: Integer; // Ole Automation varType equivalent
elType2: PPTypeInfo; // independent of cleanup
DynUnitName: ShortStringBase);
end;
Alex Konshin (2006-02-13 08:16:00) [3]TUser © (11.02.06 10:45) [17]
> Data : Array [0:-1] of Byte; // вот так, к сожалению, нельзя
А зачем?
Затем, что перевести на Pascal конструкцию из C/C++ [0] нельзя. А надо.
Например:
typedef struct _DISK_INFORMATION {
UCHAR Length[2];
UCHAR DiskStatus : 2;
UCHAR LastSessionStatus : 2;
UCHAR Erasable : 1;
UCHAR Reserved1 : 3;
UCHAR FirstTrackNumber;
UCHAR NumberOfSessions;
UCHAR LastSessionFirstTrack;
UCHAR LastSessionLastTrack;
UCHAR Reserved2 : 5;
UCHAR GEN : 1;
UCHAR DBC_V : 1;
UCHAR DID_V : 1;
UCHAR DiskType;
UCHAR Reserved3[3];
UCHAR DiskIdentification[4];
UCHAR LastSessionLeadIn[4]; // MSF
UCHAR LastPossibleStartTime[4]; // MSF
UCHAR DiskBarCode[8];
UCHAR Reserved4;
UCHAR NumberOPCEntries;
OPC_TABLE_ENTRY OPCTable[0];
} DISK_INFORMATION, *PDISK_INFORMATION;
И в VCL есть места, где массивы нулевой длины не помешали бы:
PPTypeInfo = ^PTypeInfo;
PTypeInfo = ^TTypeInfo;
TTypeInfo = record
Kind: TTypeKind;
Name: ShortString;
{TypeData: TTypeData}
end;
TPropData = packed record
PropCount: Word;
PropList: record end;
{PropList: array[1..PropCount] of TPropInfo}
end;
jack128 (2006-02-12 23:30:00) [4]Германн © (12.02.06 3:54) [18]
Чем тебе противен Pointer?
Тем, что занимает лишние 4 байта. Тем что сохранить такую запись простым Stream.WriteBuffer(MyPackegeVar, MyPackegeVar.Length); невозможно будет. Наверное поэтому..
atruhin (2006-02-12 08:02:00) [5]>>А зачем?
Тоже приходилось пользоваться. Для byte вроде незачем проще PChar, а вот если Data - record, да даже Integer удобнее не нужно каждый раз приводить тип.
например integer(Data[NumElem*SizeOf(Integer)]).
Я делал так.
TData = array [0..1000] of record ..... end;
PData = ^TData;
var
MyPackage : TMyPackage; // без Data
Data : PData;
begin
.....
Data := inc(MyPackage, SizeOf(MyPackage));
..Data^..
Германн (2006-02-12 03:54:00) [6]Кстати, Alex, а действительно зачем?
Чем тебе противен Pointer?
TUser (2006-02-11 10:45:00) [7]> Data : Array [0:-1] of Byte; // вот так, к сожалению, нельзя
А зачем?
Alex Konshin (2006-02-11 08:18:00) [8]PVOzerski © (10.02.06 17:03) [15]
А вот это кстати иногда требуется в record и очень раздражает, что в Delphi нельзя описать массив нулевой длины. Кстати, замечу, что у автора массив единичной длины.
А пример, где это нужно:
TMyPackage = record
Length : Integer;
Flags : TMyPackageFlags;
Data : Array [0:-1] of Byte; // вот так, к сожалению, нельзя
end;
const PackageHeaderSize = SizeOf(TMyPackage);
PVOzerski (2006-02-10 17:03:00) [9]В общем, я в подобных случаях иногда просто объявляю типизированную костанту
const five: integer = 5;
и потом использую как индекс массива. А вообще-то, что заставляет ограничивать верхнюю границу массива нулем при описании, в общем-то, фиктивного типа TDArray?
Leonid Troyanovsky (2006-02-10 16:41:00) [10]
> han_malign © (10.02.06 15:17) [11]
> > TDArray = array[0..MaxArraySize-1] of Integer;
> PIntegerArray - не судьба?
Может быть в нем и есть сермяжная правда.
Но, лучше б было предложить оное непосредственно вопрошаещему.
Т.е., про то "как" я, IMHO, ответил прямо, без ссылок.
--
Regards, LVT.
han_malign (2006-02-10 15:23:00) [11]palva © (10.02.06 00:13) [6]
- упс, не заметил...
han_malign (2006-02-10 15:22:00) [12]
> //А здесь ошибка на этапе компиляции
> t^[5] := 10;
- а вот здесь, что самое интересное, ее не будет:
for i:= 5 to 5 do t^[ i] := 10;
По моему, для массива с неизвестной начальной длинной, обращение по вычисляемому ииндексу более логично... Не так ли?
han_malign (2006-02-10 15:17:00) [13]
> const
> MaxArraySize = ..;
>
> type
> TDArray = array[0..MaxArraySize-1] of Integer;
> PDArray = ^TDArray;
>
PIntegerArray - не судьба?
palva (2006-02-10 10:04:00) [14]> Может лучше было бы объяснить задачу?
Это был стандартный метод моделирования динамических массивов, когда динамических массивов в Delphi не было.
Leonid Troyanovsky (2006-02-10 08:34:00) [15]
> Imm (09.02.06 23:47) [3]
> Я тут подумал взвесил все за и против и решил, что действительно
> открытим массивом воспользоваться будет удобнее, но всё
> же как откомпилировать приведённый мной код, сейчас это
> мне походу не понадобится, но на будущее будет полезно.
> Я был бы очень благодарен за ответ.
const
MaxArraySize = ..;
type
TDArray = array[0..MaxArraySize-1] of Integer;
PDArray = ^TDArray;
--
Regards, LVT.
Германн (2006-02-10 02:27:00) [16]2 imm (09.02.06 23:22)
Может лучше было бы объяснить задачу?
Я, например, никак не могу понять сабж:
type
TDArray = array[0..0] of Integer;
PDArray = ^TDArray;
implementation
procedure Hello;
var
t: PDArray;
begin
...
//Выделяем память
GetMem(t, SizeOf(Integer)*10);
//А здесь ошибка на этапе компиляции
t^[5] := 10;
...
end;
Джо (2006-02-10 00:17:00) [17]Да, действительно, слушайте [6] palva, я сегодня заработался, видимо, вот и усложняю :). Так действительно будет проще всего, кажется.
palva (2006-02-10 00:13:00) [18]{$R-} отвечает за проверку диапазона на этапе выполнения. А на этапе компиляции, судя по всему всегда производится проверка константных выражений на соответствие диапазону. Как это отключить - не понятно. Но для неконстантных выражений компилироваться будет. Например:
i := 5;
t^[i] := 10;
Джо (2006-02-10 00:07:00) [19]Только первоначальный указатель не забыть сохранить, для FreeMem.
Джо (2006-02-10 00:00:00) [20]> [3] Imm (09.02.06 23:47)
> Я тут подумал взвесил все за и против и решил, что действительно
> открытим массивом воспользоваться будет удобнее, но всё
> же как откомпилировать приведённый мной код, сейчас это
> мне походу не понадобится, но на будущее будет полезно.
> Я был бы очень благодарен за ответ.
Такоеt^[5] := 10не откомпилируешь ни с какой директивой.
А можно, как я уже и говорил, сделать так:
Inc (t,6*SizeOf(Integer));
t^[0] := ...