Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.03.19;
Скачать: CL | DM;

Вниз

$R- в созданном юните, непашет на уровне компиляции   Найти похожие ветки 

 
imm   (2006-02-09 23:22) [0]

Создаю новый юнит, пихаю туда


{$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;


Как это исправить, то есть как это откомпилировать???? Помогите пожалуйста. За раннее вам благодарен.


 
Джо ©   (2006-02-09 23:30) [1]

А почему бы не усложнять себе жизнь и не воспользоваться динамическим массивом array of Integer?


 
Джо ©   (2006-02-09 23:33) [2]

В принципе, над t, как и над любым указателем, можно выполнять операции увеличения/уменьшения, т.е, например Inc(t,SizeOf(Integer)*2) - сместит указатель на второй элемент.


 
Imm   (2006-02-09 23:47) [3]

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


 
Джо ©   (2006-02-10 00:00) [4]

> [3] Imm   (09.02.06 23:47)
> Я тут подумал взвесил все за и против и решил, что действительно
> открытим массивом воспользоваться будет удобнее, но всё
> же как откомпилировать приведённый мной код, сейчас это
> мне походу не понадобится, но на будущее будет полезно.
> Я был бы очень благодарен за ответ.

Такое t^[5] := 10 не откомпилируешь ни с какой директивой.
А можно, как я уже и говорил, сделать так:
Inc (t,6*SizeOf(Integer));
t^[0] := ...


 
Джо ©   (2006-02-10 00:07) [5]

Только первоначальный указатель не забыть сохранить, для FreeMem.


 
palva ©   (2006-02-10 00:13) [6]

{$R-} отвечает за проверку диапазона на этапе выполнения. А на этапе компиляции, судя по всему всегда производится проверка константных выражений на соответствие диапазону. Как это отключить - не понятно. Но для неконстантных выражений компилироваться будет. Например:

  i := 5;
  t^[i] := 10;


 
Джо ©   (2006-02-10 00:17) [7]

Да, действительно, слушайте [6] palva, я сегодня заработался, видимо, вот и усложняю :). Так действительно будет проще всего, кажется.


 
Германн ©   (2006-02-10 02:27) [8]

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;


 
Leonid Troyanovsky ©   (2006-02-10 08:34) [9]


> Imm   (09.02.06 23:47) [3]

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


const
 MaxArraySize = ..;

type
 TDArray = array[0..MaxArraySize-1] of Integer;
 PDArray = ^TDArray;


--
Regards, LVT.


 
palva ©   (2006-02-10 10:04) [10]

> Может лучше было бы объяснить задачу?
Это был стандартный метод моделирования динамических массивов, когда динамических массивов в Delphi не было.


 
han_malign ©   (2006-02-10 15:17) [11]


> const
>  MaxArraySize = ..;
>
> type
>  TDArray = array[0..MaxArraySize-1] of Integer;
>  PDArray = ^TDArray;
>


PIntegerArray - не судьба?


 
han_malign ©   (2006-02-10 15:22) [12]


> //А здесь ошибка на этапе компиляции
>    t^[5] := 10;

- а вот здесь, что самое интересное, ее не будет:
for i:= 5 to 5 do t^[i] := 10;
По моему, для массива с неизвестной начальной длинной, обращение по вычисляемому ииндексу более логично... Не так ли?


 
han_malign ©   (2006-02-10 15:23) [13]

palva ©   (10.02.06 00:13) [6]
- упс, не заметил...


 
Leonid Troyanovsky ©   (2006-02-10 16:41) [14]


> han_malign ©   (10.02.06 15:17) [11]

> >  TDArray = array[0..MaxArraySize-1] of Integer;

> PIntegerArray - не судьба?


Может быть в нем и есть сермяжная правда.
Но, лучше б было предложить оное непосредственно вопрошаещему.
Т.е., про то "как" я, IMHO, ответил прямо, без ссылок.

--
Regards, LVT.


 
PVOzerski ©   (2006-02-10 17:03) [15]

В общем, я в подобных случаях иногда просто объявляю типизированную костанту

const five: integer = 5;

и потом использую как индекс массива. А вообще-то, что заставляет ограничивать верхнюю границу массива нулем при описании, в общем-то, фиктивного типа TDArray?


 
Alex Konshin ©   (2006-02-11 08:18) [16]

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);


 
TUser ©   (2006-02-11 10:45) [17]

>  Data : Array [0:-1] of Byte; // вот так, к сожалению, нельзя

А зачем?


 
Германн ©   (2006-02-12 03:54) [18]

Кстати, Alex, а действительно зачем?
Чем тебе противен Pointer?


 
atruhin ©   (2006-02-12 08:02) [19]

>>А зачем?
Тоже приходилось пользоваться. Для 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^..


 
jack128 ©   (2006-02-12 23:30) [20]

Германн ©   (12.02.06 3:54) [18]
Чем тебе противен Pointer?

Тем, что занимает лишние 4 байта. Тем что сохранить такую запись простым Stream.WriteBuffer(MyPackegeVar, MyPackegeVar.Length); невозможно будет.  Наверное поэтому..


 
Alex Konshin ©   (2006-02-13 08:16) [21]

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;


 
Alex Konshin ©   (2006-02-13 08:20) [22]

Оттуда же еще пример:
 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;


 
han_malign ©   (2006-02-13 10:37) [23]


> что в Delphi нельзя описать массив нулевой длины

- ну, допустим, в С++ это, нынче, тоже нерекомендумемая конструкция - warning выдает...
И приходится делать явно:
PData pData = (PData)(pRecord +1);
а смещение следующей записи, по любому, исподподвыподверта надо вычислять
pRecordNext = (PRecord)((PBYTE)pRecord + pRecord.cbSize);



Страницы: 1 вся ветка

Текущий архив: 2006.03.19;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.027 c
2-1141299376
ANB
2006-03-02 14:36
2006.03.19
Как запихнуть LongWord в LongInt ?


3-1138197050
galexis
2006-01-25 16:50
2006.03.19
SQL запрос с многими значениями параметра.


15-1140874980
WondeRu
2006-02-25 16:43
2006.03.19
Как организовать связь между приложением и ISAPI (CGI) модулем?


2-1141485688
nsk3d
2006-03-04 18:21
2006.03.19
загрузка в проигрыватель


3-1138267273
kyn66
2006-01-26 12:21
2006.03.19
Как спрятать скроллинг по гриду ?