0

We have:

  • a uResourceTableFields.pas unit defining consts for fieldnames
    this contained SHours = 'tt_hours';
  • a uResource.pas unit containing resourcestrings
    These are use for the UI and are subject to translations

I added

SHours = 'Uren';

to uResource.pas and this compiled fine.

The next day I noticed code like

Result := AllocationData.FieldByName(SHours).AsFloat;

failed with 'field not found' ;-)
The resourcestring was substituted here!

How can we automatically prevent these kinds of conflicts at compile time?
It is not possible to limit our Uses clauses to either uResourceTableFields or uResource.

Jan Doggen
  • 8,799
  • 13
  • 70
  • 144
  • `uResourceTableFields.SHours` and `uResource.SHours`? If you only write `SHours`, this refers to the identifier in the most recently encountered unit in the `uses` lists. – Andreas Rejbrand Apr 28 '21 at 08:59
  • @AndreasRejbrand That would be quite an undertaking. I'd rather prevent (detect) the duplicate names. – Jan Doggen Apr 28 '21 at 09:01
  • It is unclear what you are asking here. You cannot automatically prevent duplicate names. What you can do is use different prefix for all your constants, so that accidental collision cannot occur, or wrap them inside static class or record. – Dalija Prasnikar Apr 28 '21 at 09:03
  • It might be worth pointing out that this doesn't have anything in particular to do with `const` strings and `resourcestring`s. You can have `var A: Integer` in `Unit1.pas` and `var B: Integer` in `Unit2.pas` and you get the exact same situation. Or functions. Or types. Or ... – Andreas Rejbrand Apr 28 '21 at 09:06
  • @AndreasRejbrand You have a point ;-) Still, I'm curious if this can be prevented other than 'manually'. Maybe with some additional initialization code at run time? But I doubt that, the const names don't exist at that stage. – Jan Doggen Apr 28 '21 at 09:14
  • Duplicate identifiers are a feature of the language and there are rules which compiler follows when resolving duplicate identifiers. http://docwiki.embarcadero.com/RADStudio/Sydney/en/Fundamental_Syntactic_Elements_(Delphi) and http://docwiki.embarcadero.com/RADStudio/Sydney/en/Declarations_and_Statements_(Delphi)#Blocks_and_Scope there is nothing you can do at the runtime, because identifiers are resolved at compile time. Maybe some static analysis tools can help you, but, again just use different naming scheme. – Dalija Prasnikar Apr 28 '21 at 09:48
  • 1
    ^^ this. Prefix your resource vars so you *know* that it is a resource string, something like Resource_SHours; – whosrdaddy Apr 28 '21 at 10:03
  • @whosrdaddy: That makes the best sense to me. – MartynA Apr 28 '21 at 11:42

0 Answers0