0

I'm working on a vintage code base and I am very new to delphi, so apologies in advance if my syntax is off a bit (or just plain wrong).

I have things like a pre defined (at compile time) array. arr and we used all over the place

  • file1.pas: arr[1] := 3.14
  • file2.pas: pi := arr[1]

And I've noticed that we never,ever use constants to access elements in the array. In C I would write:

int arr[100] = {0};
const int MY_INDEX=1;
arr[MY_INDEX] = 3.14

etc. But I don't see that in my delphi code base. Is that because Delphi/Pascal doesn't support it or because the original authors decided not to do it?

Thanks

3
  • The better question might be why you write with a constant in C. In Delphi arrays are quite often accessed by enums, if the indices have meaning. Commented Oct 29, 2013 at 8:49
  • do you have an example or link? Right now it is all magic numbers. Commented Oct 29, 2013 at 14:13
  • See the Delphi VCL (or corresponding LCL in Lazarus) and Deltics answer. Commented Oct 29, 2013 at 16:31

3 Answers 3

3

Delphi allows you to use a constant as an array index. So if you don't see such a thing in your code, it's because the authors elected not to declare and use constants for array indices.

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks! I googled for this idea but all the results I saw had to do with "array of constants", etc. Do you know of any links that would explain? Know of any best practices or patterns for delphi dev?
Explain what? I thought I already covered all that you asked.
@cbrulak: If arr is an array, then arr[something] is syntactically valid as long as something evaluates to a natural number. For instance, arr[Round(Abs(500*Sin(2.1)))] works. As a corollary, any contant representing a natural number will do.
Sorry for the confusion. I meant, like an actual doc that spells that out. This (icecube.wisc.edu/~dglo/c_class/array_ptr.html) is a good example of what i'm asking for. I just need something to kick off a discussion and a doc is better food for thought.
|
2

Yes constants can be used along with any expression that evaluates to an appropriate and valid index for the array. You should also note that an array in Delphi could be declared with a non-zero based index range:

var
  MonthlyTotals: array[1..12] of Integer;  // Jan = 1, Feb = 2 etc etc

You can even specify the index of an array as an enum type and use enum members for the indices which provides even tighter safety (where possible and appropriate), as per this contrived example:

type
  TFileFormat = (ffXML, ffCSV, ffText, ffJSON);

var
  sExtensions: array[TFileFormat] of String;

sExtensions[ffXML]  := 'xml';
sExtensions[ffCSV]  := 'csv';
sExtensions[ffText] := 'txt';
sExtensions[ffJSON] := 'json';

In such cases the array might only have members for certain (contiguous) values in the enum:

var
  sExtensions: array[ffXML..ffCSV] of String;

For this reason, and the fact that array indices may not be zero based, unless you are 110% certain of the index range of an array it is a good idea to always use Low() and High() to determine the index bounds when iterating over the contents of an array and not assume the index basis:

  // This will not work properly:
  for i := 0 to 11 do
    MonthlyTotals[i] := ....

  // Neither will this, even though it looks more safe
  for i := 0 to Pred(Length(MonthlyTotals)) do
    MonthlyTotals[i] := ....

  // This will be safe:
  for i := Low(MonthlyTotals) to High(MonthlyTotals) do
    MonthlyTotals[i] := ....

  // And it works for enum indices as well:
  for ext := Low(sExtensions) to High(sExtensions) do
    sExtensions[ext] := ....

5 Comments

Wouldn't it be more of a better idea to use For...in? :-)
I knew someone would say that. First of all, that would be making assumptions about the version of Delphi being used. I'm also a firm believer in grasping the basics before taking short-cuts, otherwise you risk making mistakes arising from that lack of basic understanding and given that the OP doesn't have a comprehensive understanding of the /very/ basics, it would be premature to jump ahead to advanced syntax with it's own limitations (e.g. the inability to process the array in reverse order, for example, if that were important - which it might be).
@Deltics - for/in isn't new, and isn't 'advanced' - conceptually it's more basic than for/to. The real reason you didn't use it is because you were making assignments to the thing being enumerated ;-)
Now, if only we had a proper for/in loop like D or C++.
@Chris - it is "new" for some (a lot of) people who are still using older versions of Delphi and perhaps only now upgrading that code (if at all). And yes, that is another limitation that makes it inappropriate for these (admittedly contrived) examples and I think it is significant that this detail was missed by the first person to suggest using "for in" as a better idea (and indeed even overlooked by myself in my response). ;)
0

The exact conversion of your C code in Delphi would be along the lines of:

var
  arr: array[100] of integer;
const
  MY_INDEX = 1;
begin
  arr[MY_INDEX] := 3.14;
end;

As others have said, perfectly feasible and the enum method is arguably a better alternative. One gotcha here is that this is relying on Delphi having the array initialised zeroed rather than setting it explicitly as in C.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.