Jump to content
Sign in to follow this  
DelphiUdIT

Absolute directive with record and array

Recommended Posts

Hello everyone.
From a post in the international Lazarus forum ( https://forum.lazarus.freepascal.org/index.php/topic,71183.msg555336.html#msg555336 ) I noticed the use of the "absolute" directive to actually initialize an array of records.
By defining an initialized array of strings, these are then fully matched to an array of records.
I knew about the "absolute" directive, but honestly I have never seen it applied (or at least I have never noticed it, I vaguely remember seeing it in Indy).
Apart from other ways to obtain the same results, does the definition as it was made have any contraindications other than the pure reading of an element of the record (I think of its writing or passing as a "var" to some processing method)?

Sample:

const
  TABLE_SIZE = 118; //118*3 -1 = array size

  TABLE_DATA: array[0..pred(TABLE_SIZE * 3)] of string = (
  'H', 'Hydrogen', '1.00794', 'He', 'Helium', '4.002602',
  'Li', 'Lithium', '6.941', 'Be', 'Beryllium', '9.012182',
  'B', 'Boron', '10.811', 'C', 'Carbon', '12.0107',
  'N', 'Nitrogen', '14.0067', 'O', 'Oxygen', '15.9994',
  'F', 'Fluorine', '18.9984032', 'Ne', 'Neon', '20.1797',
  'Na', 'Sodium', '22.98976...', 'Mg', 'Magnesium', '24.305',
  'Al', 'Aluminium', '26.9815386', 'Si', 'Silicon', '28.0855',
  'P', 'Phosphorus', '30.973762', 'S', 'Sulfur', '32.065',
  'Cl', 'Chlorine', '35.453', 'Ar', 'Argon', '39.948',
  'K', 'Potassium', '39.948', 'Ca', 'Calcium', '40.078',
  'Sc', 'Scandium', '44.955912', 'Ti', 'Titanium', '47.867',
  'V', 'Vanadium', '50.9415', 'Cr', 'Chromium', '51.9961',
  'Mn', 'Manganese', '54.938045', 'Fe', 'Iron', '55.845',
  'Co', 'Cobalt', '58.933195', 'Ni', 'Nickel', '58.6934',
  'Cu', 'Copper', '63.546', 'Zn', 'Zinc', '65.38',
  'Ga', 'Gallium', '69.723', 'Ge', 'Germanium', '72.63',
  'As', 'Arsenic', '74.9216', 'Se', 'Selenium', '78.96',
  'Br', 'Bromine', '79.904', 'Kr', 'Krypton', '83.798',
  'Rb', 'Rubidium', '85.4678', 'Sr', 'Strontium', '87.62',
  'Y', 'Yttrium', '88.90585', 'Zr', 'Zirconium', '91.224',
  'Nb', 'Niobium', '92.90628', 'Mo', 'Molybdenum', '95.96',
  'Tc', 'Technetium', '(98)', 'Ru', 'Ruthenium', '101.07',
  'Rh', 'Rhodium', '102.9055', 'Pd', 'Palladium', '106.42',
  'Ag', 'Silver', '107.8682', 'Cd', 'Cadmium', '112.411',
  'In', 'Indium', '114.818', 'Sn', 'Tin', '118.71',
  'Sb', 'Antimony', '121.76', 'Te', 'Tellurium', '127.6',
  'I', 'Iodine', '126.90447', 'Xe', 'Xenon', '131.293',
  'Cs', 'Caesium', '132.9054', 'Ba', 'Barium', '132.9054',
  'La', 'Lanthanum', '138.90547', 'Ce', 'Cerium', '140.116',
  'Pr', 'Praseodymium', '140.90765', 'Nd', 'Neodymium', '144.242',
  'Pm', 'Promethium', '(145)', 'Sm', 'Samarium', '150.36',
  'Eu', 'Europium', '151.964', 'Gd', 'Gadolinium', '157.25',
  'Tb', 'Terbium', '158.92535', 'Dy', 'Dysprosium', '162.5',
  'Ho', 'Holmium', '164.93032', 'Er', 'Erbium', '167.259',
  'Tm', 'Thulium', '168.93421', 'Yb', 'Ytterbium', '173.054',
  'Lu', 'Lutetium', '174.9668', 'Hf', 'Hafnium', '178.49',
  'Ta', 'Tantalum', '180.94788', 'W', 'Tungsten', '183.84',
  'Re', 'Rhenium', '186.207', 'Os', 'Osmium', '190.23',
  'Ir', 'Iridium', '192.217', 'Pt', 'Platinum', '195.084',
  'Au', 'Gold', '196.966569', 'Hg', 'Mercury', '200.59',
  'Tl', 'Thallium', '204.3833', 'Pb', 'Lead', '207.2',
  'Bi', 'Bismuth', '208.9804', 'Po', 'Polonium', '(209)',
  'At', 'Astatine', '(210)', 'Rn', 'Radon', '(222)',
  'Fr', 'Francium', '(223)', 'Ra', 'Radium', '(226)',
  'Ac', 'Actinium', '(227)', 'Th', 'Thorium', '232.03806',
  'Pa', 'Protactinium', '231.0588', 'U', 'Uranium', '238.02891',
  'Np', 'Neptunium', '(237)', 'Pu', 'Plutonium', '(244)',
  'Am', 'Americium', '(243)', 'Cm', 'Curium', '(247)',
  'Bk', 'Berkelium', '(247)', 'Cf', 'Californium', '(251)',
  'Es', 'Einstenium', '(252)', 'Fm', 'Fermium', '(257)',
  'Md', 'Mendelevium', '(258)', 'No', 'Nobelium', '(259)',
  'Lr', 'Lawrencium', '(262)', 'Rf', 'Rutherfordium', '(267)',
  'Db', 'Dubnium', '(268)', 'Sg', 'Seaborgium', '(271)',
  'Bh', 'Bohrium', '(272)', 'Hs', 'Hassium', '(270)',
  'Mt', 'Meitnerium', '(276)', 'Ds', 'Darmstadium', '(281)',
  'Rg', 'Roentgenium', '(280)', 'Cn', 'Copernicium', '(285)',
  'Nh', 'Nihonium', '(286)', 'Fl', 'Flerovium', '(289)',
  'Mc', 'Moscovium', '(290)', 'Lv', 'Livermorium', '(293)',
  'Ts', 'Tennessine', '(294)', 'Og', 'Oganesson', '(294)');

var
  Elements : array[0..pred(TABLE_SIZE)] of record
    Symbol     : string;
    Name       : string;
    Mass       : string;
  end absolute TABLE_DATA;  { absolute, don't program without it !! }


procedure XXXXX
begin
  for var i in Elements do
    begin
      ShowMessage(i.Symbol+' / '+i.Name+' / '+i.Mass);
    end;
end;


Thanks

 

EDIT: the question is for TABLE_DATA defined as "var" of course, not as "const" ...

Edited by DelphiUdIT
  • Like 1

Share this post


Link to post

Nice.
To handle it more effectively, I would encapsulate this const array in an Enum with a record helper.
That allows to add a lot of convenience functions around this table and offers a nice and effective Enum handle.

Edited by Rollo62
  • Thanks 1

Share this post


Link to post

I don't understand the question but... while absolute has its uses, in this case it would IMO just be laziness on the part of the developer. And what's up with the use of pred? Since when did that become more readable than -1 ?

  • Thanks 1

Share this post


Link to post
1 hour ago, Anders Melander said:

And what's up with the use of pred? Since when did that become more readable than -1 ?

It survives the change from Integer to an enumeration type.

  • Thanks 1

Share this post


Link to post
4 minutes ago, Uwe Raabe said:

It survives the change from Integer to an enumeration type.

What change? You mean a possible future change of the index type?

 

I can't see how any of the Pred used here would survive that:

TABLE_DATA: array[0..pred(TABLE_SIZE * 3)] of string
Elements : array[0..pred(TABLE_SIZE)] of record

 

Regardless, if I changed the index type I would want to review the implications of that change manually and not assume that it just worked - especially with absolute in the game.

Share this post


Link to post

What are you trying to achieve here? As Stefan says, why aren't you declaring these as records to begin with? And why would you want to make anything here a variable. Seems like this area of Physics is pretty much fixed!

  • Thanks 1

Share this post


Link to post
2 hours ago, Stefan Glienke said:

where mass would be a number instead of a string

I think the use of string here is to allow encoding of indeterminate masses for elements with no stable isotopes, or something along those lines. Look at the items with mass surrounded by parens.

Share this post


Link to post

It is not mine, I'm not a chemical tech. I only see the use of the "absolute" directive and ask if there is any issue (in assignement for example). By the way I have tested some uses case and i don't found any issue, it's like a normal array of records.

Like I wrote, I had know that there are other methods, I was only curious about "absolute" used in array of records.

 

Thank you all for your interest.

Share this post


Link to post
52 minutes ago, Anders Melander said:

What change? You mean a possible future change of the index type?

 

I can't see how any of the Pred used here would survive that:


TABLE_DATA: array[0..pred(TABLE_SIZE * 3)] of string
Elements : array[0..pred(TABLE_SIZE)] of record

 

The use of pred here is only the result of copy / paste operation. But I use pred sometimes, especially when there is a dimension of an array in play. In a for / to cycle instead I use normally "-1".

 

Share this post


Link to post

The only issue with absolute that I can think of is that the compiler treats the aliased variables as "volatile" which inhibits certain optimizations - AFAIR. Apart from that it's just like a hard typecast.

 

Of course one has to avoid doing stupid things like using absolute on managed types.

Share this post


Link to post
1 minute ago, Anders Melander said:

The only issue with absolute that I can think of is that the compiler treats the aliased variables as "volatile" which inhibits certain optimizations - AFAIR. Apart from that it's just like a hard typecast.

 

Of course one has to avoid doing stupid things like using absolute on managed types.

You are right, those were my fear.

Share this post


Link to post
Just now, DelphiUdIT said:

But I use pred sometimes, especially when there is a dimension of an array in play.

Use High(MyArray) instead; It clearly communicates what your intentions are.

 

IMO, using Succ and Pred for anything other than enumerations is like using Assigned on pointers (even object pointers). On delegates it makes sense, but for everything else I think (FooBar <> nil) is more readable and better communicate intention than Assigned(FooBar). I'm sure everybody agrees with me on that 😉

Share this post


Link to post
4 minutes ago, DelphiUdIT said:

You are right, those were my fear. 

If you mean the volatile thing then it's not a problem unless you are doing high performance low-level stuff. AFAIR the worst that can happen is that a value is kept on the stack instead of in a register.

Share this post


Link to post
23 minutes ago, Anders Melander said:

is like using Assigned on pointers (even object pointers). On delegates it makes sense, but for everything else I think (FooBar <> nil) is more readable and better communicate intention than Assigned(FooBar). I'm sure everybody agrees with me on that 😉

Lool, I always use Assigned(...) hoping that one day or another it will solve all the situations (either nil or an invalid pointer) 🙂

Edited by DelphiUdIT

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×