|
User-contributed comments | |
Christopher Burke 31 Aug 2001 01:20 AM GMT |
Hasn't Delphi always allocated
A,B:integer;
as ONE block and
A:integer;
B:integer;
as TWO blocks ?
And therefore this isn't really a bug ?
Jordan Russell 06 Sep 2001 07:54 PM GMT |
It has always been my understanding that "A, B: Type" should be equivalent to "A: Type; B: Type". The former is just a shorthand notation for the latter. They shouldn't function differently.
Christian NineBerry Schwarz 06 Sep 2001 08:37 PM GMT |
There have always been differences:
var
A: array[1..10] of byte;
B: array[1..10] of byte;
C, D: array[1..10] of byte;
begin
C:= D; // Compiles fine
A:= B; // Type mismatch from Turbo Pascal 1 to Delphi 6
end; |
Jordan Russell 09 Sep 2001 03:51 AM GMT |
Ah, that's true. But that's because the compiler sees it as:
var
A: Type1;
B: Type2;
C, D: Type3; |
Each time you declare a variable without using a pre-defined type, the compiler internally allocates a new type. That's why A and B aren't assignment compatible.
Arsène von Wyss 09 Oct 2001 11:23 PM GMT |
I don't see why this would be a bug, at most I'd call it a gotcha. Only when a record is declared as "packed" you can assume what structure the record will exactly have. Every other declaration leaves it to the compiler to do whatever it wants with the fields as long as they remain available, and this includes aligning.
While it is certainly strange that the compiler does not use the same alignment in these situations, the compiler pretty well does align the way one could assume is useful. For instance, if I declare:
type
Test1=record
a,b,c,d: Byte;
end;
|
it optically looks as if these bytes form one group. However, if I declare it like this:
type
Test2=record
a: Byte;
b: Byte;
c: Byte;
d: Byte;
end;
|
then it looks much more like four separated byte entries. It seems to me that a programmer will usually choose the "style" which represents what he is thinking about, and therefore I don't see any wrongdoing of the compiler if it aligns comma-separated values other than line-separated ones.
Marcelo González Bergweiler 19 Nov 2001 05:49 PM GMT |
This is certainly a bug if you use records with variant parts.
Consider the following code:
type tV2 = record case byte of
1: (x,y: extended); {BUG bypassed}
{ 1: (x: real;
y: real); {BUG if not PACKED}
2: (u: array[1..2] of extended); end;
tV4 = record case integer of
1: (v: array[1..4] of extended);
2: (n: array[1..2] of tV2); end; {BUG if not PACKED}
procedure TForm1.FormActivate(Sender: TObject);
var v4 : tV4;
v2 : tV2;
begin
Memo.Clear;
with Memo.Lines do begin
Add(' OK if comma-separated:');
Add(' sizeof(v2): '+inttostr(sizeof(v2)));
Add(' longword(@v2.x): '+inttostr(longword(@v2.x)));
Add(' longword(@v2.y): '+inttostr(longword(@v2.y)));
Add('');
Add(' longword(@v2.u[1]): '+inttostr(longword(@v2.u[1])));
Add(' longword(@v2.u[2]): '+inttostr(longword(@v2.u[2])));
Add('');
Add(' BUG: n[2]<>v[3]');
Add(' sizeof(v4): '+inttostr(sizeof(v4)));
Add(' longword(@v4.n[1]): '+inttostr(longword(@v4.n[1])));
Add(' longword(@v4.n[2]): '+inttostr(longword(@v4.n[2])));
Add('');
Add(' longword(@v4.v[1]): '+inttostr(longword(@v4.v[1])));
Add(' longword(@v4.v[3]): '+inttostr(longword(@v4.v[3])));
Add(''); end;
end;
|
The variant parts n[2].u[1] and v[3] in v4 do not allign properly.
This is certainly not correct. The same problem happens if REAL48 (6 bytes) is used instead of extended (10 bytes).
Also I do not agree that declaring records separately (by not using commas)
is good. The opposite is better in this case (see v2 variable).
My suggestion for a workaround is to use the {$ALIGN OFF} switch once on top of the source code and wait until the bug is corected by Borland. Otherwise you have to use PACKED records on every record with variants you define.
My Delphi is version 6.01.
Arsène von Wyss 29 Nov 2001 10:53 PM GMT |
The compiler is allowed to align data freely as long as the record is not marked as packed. How the data is aligned does not matter in normal applications, even if a variant record is used without the intention to use it the dirty way (that is, to write some data on a variant and read data using another one).
The problem only arises when you, as a programmer, assume a certain data alignment. However, the alignment may (and does) change with the different Delphi versions, and therfore the only correct solution is to pack these records. If, and only if, they are declared as packed, you have the knowledge over the used alignment, and it will be correct. Therefore I still don't see any *bug* in the compiler, even if the behaviour is unexpected. If your code does not work because you didn't declare a record it as packed, its *your* bug, not a compiler one.
bin 30 Jan 2003 04:46 PM GMT |
Well I haven't tried none of the examples, but if they really work as they are said, then I think this is a bug. Using variant records "the dirty way" is a very normal programming technique, and if you dig for a while in the sources of the delphi libraries you could see this. The thing is that a packed record was used, and the reason was that it was an imported struct from a C header file. The question is whether they would use packed if it wasnt...
|
|