Recent

Author Topic: Can Absolute be used on string / packed record  (Read 2890 times)

andresayang

  • Jr. Member
  • **
  • Posts: 74
Can Absolute be used on string / packed record
« on: June 27, 2022, 08:59:49 pm »
Hello,

I build a packet record of shot strings, can I use Absolute directive to split a short string in several parts of my packed record ?
Or is there any way to do something like:

Code: Pascal  [Select][+][-]
  1. var
  2. splitline: MyPackedRecord;
  3. line : String[100]; (100 is the size on my packed record)
  4.  
  5. splitline:= line; ( to have direct acces to plitline.record without having to use copy function)
  6.  
  7.  
Cheers
Linux, Debian 12
Lazarus: always latest release

Awkward

  • Full Member
  • ***
  • Posts: 108
Re: Can Absolute be used on string / packed record
« Reply #1 on: June 27, 2022, 09:28:56 pm »
You can use 'Absolute' for string (why not?)
but looks like you forgot one thing. string[100] is 101 bytes length coz first byte will be used to keep line length
so? code
Code: Pascal  [Select][+][-]
  1. var
  2.   splitline: MyPackedRecord;
  3.   line: string[100] absolute splitline;
  4.  
can be compiled but line[1] will be not first byte of record but second byte
We born to save world from bugs and nazies.

andresayang

  • Jr. Member
  • **
  • Posts: 74
Re: Can Absolute be used on string / packed record
« Reply #2 on: June 27, 2022, 10:23:52 pm »
Hi,

Well, the way I understood it (Absolute), it should be the other way:

Code: Pascal  [Select][+][-]
  1. var
  2.   line: string[100];
  3.   splitline: MyPackedRecord absolute of line;
  4.  

This is the way I codded it, and it seems to do not work. Maybe due to each short string of splitline having one additional byte
  • ...
Linux, Debian 12
Lazarus: always latest release

Bart

  • Hero Member
  • *****
  • Posts: 4724
    • Bart en Mariska's Webstek
Re: Can Absolute be used on string / packed record
« Reply #3 on: June 27, 2022, 10:51:35 pm »
I would say that practically it is not possible.
Let's say MyPackedRecord consists of 2 shortsstrings (SA and SB) with length A and B, such that A + B = 100-2.
Now your shortstring Line has the exact same memory layout as MyPackedRecord since you declared one to be absolute the other.

If you want to use Line to populate MyPackedRecord (which is what I understand from your posts), then Line[0] must be the length of the first shortstring in MyPackedRecord (SA), but Line[A+1] maps to the 0-th byte of the second shortstring (SB), which is the length indicator for that string, so it must be the length of the second string.
While in theory that is possible, it would be more difficult to make it so than just accessing the individual shortstrings of MyPackedRecord.
You certainly would not be able to read Line from a file (or console) and correctly map it to MyPackedRecord.

The same argument goes for the other way around.

Bart

andresayang

  • Jr. Member
  • **
  • Posts: 74
Re: Can Absolute be used on string / packed record
« Reply #4 on: June 27, 2022, 11:06:43 pm »
@Bart:
Yep, this is what I realize when I was remind that short string have 1 byte more (byte 0) for length.

So do you have an optimized technique to do "column separated values" of text file or we absolutely need to use Copy(S, start, length) ?

Thanks
Linux, Debian 12
Lazarus: always latest release

Bart

  • Hero Member
  • *****
  • Posts: 4724
    • Bart en Mariska's Webstek
Re: Can Absolute be used on string / packed record
« Reply #5 on: June 28, 2022, 06:45:16 pm »
Depends on the format of the file.
There are components that read/write CSV files.
Most likely they internally use Copy() and other string manipulating routines.

Bart

MarkMLl

  • Hero Member
  • *****
  • Posts: 4753
Re: Can Absolute be used on string / packed record
« Reply #6 on: June 28, 2022, 08:25:34 pm »
You can use 'Absolute' for string (why not?)

Because in the general case "a string" might be a shortstring (e.g. string[100] with 100 + 1 elements) or an ansistring etc. where the descriptor (term used loosely) is an opaque data structure referencing the actual text which is stored on the heap.

I'd expect absolute to be applicable to the first case, but not- safely- to the second.

I'd similarly expect the first case to be safe in a (Pascal-style) record which describes a record in a file, but not- safely- the second.

That's why, if you're messing with a low-level API and need the address of the text in a string S, you always use @S[1] rather than @S which might be stored non-contiguously.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 10175
  • FPC developer.
Re: Can Absolute be used on string / packed record
« Reply #7 on: June 28, 2022, 09:45:05 pm »
Because in the general case "a string" might be a shortstring (e.g. string[100] with 100 + 1 elements) or an ansistring etc. where the descriptor (term used loosely) is an opaque data structure referencing the actual text which is stored on the heap.

Declared with [] it will be a shortstring.

MarkMLl

  • Hero Member
  • *****
  • Posts: 4753
Re: Can Absolute be used on string / packed record
« Reply #8 on: June 28, 2022, 10:14:39 pm »
Declared with [] it will be a shortstring.

Yes, I'm attempting to qualify an overbroad assertion (not from OP).

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

jamie

  • Hero Member
  • *****
  • Posts: 4679
Re: Can Absolute be used on string / packed record
« Reply #9 on: June 29, 2022, 12:53:24 am »
what find interesting is this generating an internal error!

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. Var
  3.   S:string[100];
  4.   A:Char absolute S[1];
  5. begin
  6.   //
  7. end;      
  8.  

S is a short string so it should allow this but I get an internal compiler error.

The only true wisdom is knowing you know nothing

howardpc

  • Hero Member
  • *****
  • Posts: 3988
Re: Can Absolute be used on string / packed record
« Reply #10 on: June 29, 2022, 04:50:32 am »
The following is somewhat over-engineered, perhaps it could be simplified, however I think it achieves what you are after using Pascal union-type records rather than absolute, utilising so-called variant parts. However I hesitate to use the word "variant" since it can potentially and confusingly have several incompatible meanings.

Code: Pascal  [Select][+][-]
  1. program SplitShortStringsInRecord;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$ModeSwitch advancedrecords}
  5.  
  6. uses
  7.   {$IFDEF UNIX}
  8.   cthreads,
  9.   {$ENDIF}
  10.   LazLogger;
  11.  
  12. type
  13.  
  14.   TStr25 = String[25];
  15.   TStr40 = String[40];
  16.   TStr73 = String[73];
  17.  
  18.   TMyTripleShortstringsRec = packed record
  19.     s73: TStr73;
  20.     s40: TStr40;
  21.     s25: TStr25;
  22.     procedure Init(a25: TStr25; a40: TStr40; a73: TStr73);
  23.     procedure PrintIndividualValues;
  24.     procedure PrintComposite;
  25.   end;
  26.  
  27.   TMyPackedShortstringRecord = packed record
  28.     individuated: TMyTripleShortstringsRec;
  29.     procedure PrintComposite;
  30.   end;
  31.  
  32. var
  33.   packedRec: TMyPackedShortstringRecord;
  34.  
  35. procedure TMyPackedShortstringRecord.PrintComposite;
  36. begin
  37.   individuated.PrintComposite;
  38. end;
  39.  
  40. procedure TMyTripleShortstringsRec.Init(a25: TStr25; a40: TStr40; a73: TStr73);
  41. begin
  42.   Self := Default(TMyTripleShortstringsRec);
  43.   s25 := a25;
  44.   s40 := a40;
  45.   s73 := a73;
  46. end;
  47.  
  48. procedure TMyTripleShortstringsRec.PrintComposite;
  49. begin
  50.   DebugLn('composite: "%s%s%s"', [s73, s40, s25]);
  51. end;
  52.  
  53. procedure TMyTripleShortstringsRec.PrintIndividualValues;
  54. begin
  55.   DebugLn('s25: "%s"', [s25]);
  56.   DebugLn('s40: "%s"', [s40]);
  57.   DebugLn('s73: "%s"', [s73]);
  58. end;
  59.  
  60. begin
  61.   packedRec.individuated.Init('test s25', 'test s40 which is a bit longer', 'test s75, the longest shortstring that this record contains');
  62.   DebugLnEnter(['  PrintComposite', '']);
  63.   packedRec.PrintComposite;
  64.   DebugLn;
  65.   DebugLnEnter(['', '  PrintIndividualValues']);
  66.   packedRec.individuated.PrintIndividualValues;
  67.   DebugLn;
  68.   DebugLnExit(['', 'Press Enter to finish']);
  69.   ReadLn;
  70. end.

MarkMLl

  • Hero Member
  • *****
  • Posts: 4753
Re: Can Absolute be used on string / packed record
« Reply #11 on: June 29, 2022, 09:17:41 am »
S is a short string so it should allow this but I get an internal compiler error.

Why should it allow it? I don't think it's reasonable to apply absolute to an element in the middle of what is effectively an array, although I agree that an explicit error would be in order.

MarkMLl


MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

y.ivanov

  • Sr. Member
  • ****
  • Posts: 443
Re: Can Absolute be used on string / packed record
« Reply #12 on: June 29, 2022, 09:35:20 am »
@Bart:
Yep, this is what I realize when I was remind that short string have 1 byte more (byte 0) for length.

So do you have an optimized technique to do "column separated values" of text file or we absolutely need to use Copy(S, start, length) ?

Thanks

Why you didn'd just go with PChar's (ASCIIZ) strings and replace commas with #0? (Hope it is a single-byte encoded string)
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

PascalDragon

  • Hero Member
  • *****
  • Posts: 4303
  • Compiler Developer
Re: Can Absolute be used on string / packed record
« Reply #13 on: June 29, 2022, 01:55:38 pm »
what find interesting is this generating an internal error!

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. Var
  3.   S:string[100];
  4.   A:Char absolute S[1];
  5. begin
  6.   //
  7. end;      
  8.  

S is a short string so it should allow this but I get an internal compiler error.

Please report as a bug with a self contained example (without LCL dependencies). Whether this should be allowed or not is up to discussion, but an internal error definitely shouldn't happen.

Warfley

  • Hero Member
  • *****
  • Posts: 910
Re: Can Absolute be used on string / packed record
« Reply #14 on: June 29, 2022, 02:32:11 pm »
I know that I'm beating a dead horse here, but "absolute" is terible and should be always avoided.  The reason for this is that absolute circumvents any typechecking

E.g.
Code: Pascal  [Select][+][-]
  1. type
  2.   TTest = record
  3.     A: Integer;
  4.     B: Double
  5.   end;
  6.  
  7. var
  8.   t: TTest;
  9.   a: Integer absolute t.A;
  10.   B: Double absolute t.B;
  11. begin
  12.   t.A := 42;
  13.   t.B := 3.14;
  14.   WriteLn(a, ' ', b);
  15.   ReadLn;
  16. end.
Works really nice, but what if I now decide to change the type of TTest (which btw could be in a completely different unit, by a person who does not know that this code using absolute exists):
Code: Pascal  [Select][+][-]
  1. type
  2.   TTest = record
  3.     A: Double;
  4.     B: Double
  5.   end;
  6.  
  7. var
  8.   t: TTest;
  9.   a: Integer absolute t.A;
  10.   B: Double absolute t.B;
  11. begin
  12.   t.A := 42;
  13.   t.B := 3.14;
  14.   WriteLn(a, ' ', b);
  15.   ReadLn;
  16. end.
Now the program compiles fine, not a single hint or warning. But when running the result is now "0 3.14" rather than "42 3.14", which is wrong. This is the worst kind of error, one where it silently produces a wrong result without any crash, warning or even a compiler hint.

This is just an error waiting to happen. You should always write your code in a way that errors are cought as early as possible, best is if the compiler itself finds your error and does not compile. This is the complete opposite of this. In a perfect world we would have compilers that exactly know what you want to do and if you do something wrong, like the thing above, tell you "Sorry Dave, I can't let you do that". But sadly this is impossible so we as programmers need to restrict ourselves to tools that help the compiler to help us. But absolute is like telling the compiler "I don't need any help, I will never do mistakes"

For an example, if I do the same in C++, using references, which basically is the same as absolute but as active part of the typesystem it fully incorporates typechecking:
Code: C  [Select][+][-]
  1.     struct {
  2.         int A;
  3.         double B;
  4.     } t;
  5.     int &a = t.A;
  6.     double &b = t.B;
  7.    
  8.     t = { .A = 42, .B = 3.14 };
  9.    
  10.     std::cout << a << " " << b << std::endl;
  11. }
Changing the A field to double will cause a compiler error, which is good, because accessing an double as an integer is most probably going to be an error.
« Last Edit: June 29, 2022, 02:36:37 pm by Warfley »

 

TinyPortal © 2005-2018