Recent

Author Topic: Enum visibility across units  (Read 1106 times)

MaxM74

  • New Member
  • *
  • Posts: 33
Enum visibility across units
« on: May 23, 2025, 01:27:02 pm »
In this test, two units are used:
Unit1 and Unit2.

The types in Unit1 are aliases of Unit2 like this:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses Unit2;
  6.  
  7. type
  8.   TypeEnum = Unit2.TypeEnum;
  9.   TypeRecord = Unit2.TypeRecord;
  10.  
  11. implementation
  12.  
  13. end.
  14.  

In Unit2 i've:

Code: Pascal  [Select][+][-]
  1. unit Unit2;
  2.  
  3. interface
  4.  
  5. type
  6.   TypeEnum = (
  7.     ruNone,
  8.     ruPixelsPerInch,
  9.     ruPixelsPerCentimeter);
  10.  
  11.   TypeRecord = record
  12.     dummyField: Integer;
  13.   end;
  14.  
  15. implementation
  16.  
  17. end.
  18.  

Using Unit1 in a project like this

Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. uses Unit1;
  4.  
  5. function AFunction(AParam1: Single;
  6.                    AParam2: TypeRecord): Single;
  7. begin
  8.   Result:= AParam1+AParam2.dummyField;
  9. end;
  10.  
  11. function AFunction(AParam1: Single;
  12.                    AParam2: TypeEnum=ruPixelsPerInch;              //ERROR HERE
  13.                    AParam3: TypeRecord): Single;
  14. begin
  15.   Result:= AParam1+AParam3.dummyField;
  16. end;
  17.  
  18. begin
  19.   AFunction(3.1234, ruPixelsPerCentimeter);
  20. end.
  21.  

result in a compiler Error   :   Project1.lpr(12,38) Error: Identifier not found "ruPixelsPerInch".

while it does not give an error when using the record field dummyField.

Can someone explain to me why? I think it is a language problem since the same Test gives the same errors on Delphi 12.



Thaddy

  • Hero Member
  • *****
  • Posts: 17198
  • Ceterum censeo Trump esse delendam
Re: Enum visibility across units
« Reply #1 on: May 23, 2025, 01:36:55 pm »
It is not a language problem, but a scoping problem, programmer error.
Simply add the unit with the enum to the uses clause.

This is the same in other languages like C or C++.

The issue is: blame yourself.
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8819
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Enum visibility across units
« Reply #2 on: May 23, 2025, 01:39:40 pm »
It's a scoping problem, while the type is aliased, the possible values are still in the unit2, you don't get them unqualified without explicitly uses unit2. However, you can get them qualified:
Code: Pascal  [Select][+][-]
  1. AParam2: TypeEnum=TypeEnum.ruPixelsPerInch;
  2.  
will do.

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Enum visibility across units
« Reply #3 on: May 23, 2025, 01:40:20 pm »
while it does not give an error when using the record field dummyField.

Can someone explain to me why? I think it is a language problem since the same Test gives the same errors on Delphi 12.
Record fields are not the same as enumerated types.

You are most likely running into scoped enums.

Ah, Leledumbo was faster. So, what he said  :)
Today is tomorrow's yesterday.

Thaddy

  • Hero Member
  • *****
  • Posts: 17198
  • Ceterum censeo Trump esse delendam
Re: Enum visibility across units
« Reply #4 on: May 23, 2025, 01:44:28 pm »
This is not about scoped enums, although Handoko's example would fix it.
The way out is simply to add the unit to the uses clause.
That is all: programmer error.
(Delphi refused it too......)
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Enum visibility across units
« Reply #5 on: May 23, 2025, 02:02:35 pm »
@Thaddy:
I would encourage to have a closer look.

@MaxM74:
Nice. After fixing the enums the build results in an internal error "200212142" (already reported).
Today is tomorrow's yesterday.

cdbc

  • Hero Member
  • *****
  • Posts: 2217
    • http://www.cdbc.dk
Re: Enum visibility across units
« Reply #6 on: May 23, 2025, 02:06:54 pm »
Hi
Hmmmm...
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses Unit2;
  6.  
  7. const
  8.   lruNone = unit2.TypeEnum.ruNone;
  9.   lruPixelsPerInch = unit2.TypeEnum.ruPixelsPerInch; //HERE
  10.   lruPixelsPerCentimeter = unit2.TypeEnum.ruPixelsPerCentimeter;
  11.  
  12. type
  13.   TypeEnum = Unit2.TypeEnum;
  14.   TypeRecord = Unit2.TypeRecord;
  15.  
  16. implementation
  17.  
  18. end.
  19.  
I dunno if you can use the same name in the consts as in the enums?!?
That's why I prefixed them with (l) for local, worth a test though...
<Untested code>
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

BrunoK

  • Hero Member
  • *****
  • Posts: 698
  • Retired programmer
Re: Enum visibility across units
« Reply #7 on: May 23, 2025, 02:41:18 pm »
In program Project1 the function
Code: Pascal  [Select][+][-]
  1. function AFunction(AParam1: Single;
  2.                    AParam2: TypeEnum=ruPixelsPerInch;              //ERROR HERE
  3.                    AParam3: TypeRecord): Single;
is incorrect. The parameter(s) with default value(s) must be the last in the function declaration.

Then declaring parameters like Leledumbo did solves some other errors.

circular

  • Hero Member
  • *****
  • Posts: 4441
    • Personal webpage
Re: Enum visibility across units
« Reply #8 on: May 23, 2025, 02:50:14 pm »
Thank you cdbc, importing the values of the enums was the solution to our problem.

Your constructive approach is much appreciated!  :)
Conscience is the debugger of the mind

circular

  • Hero Member
  • *****
  • Posts: 4441
    • Personal webpage
Re: Enum visibility across units
« Reply #9 on: May 23, 2025, 03:01:04 pm »
It's a scoping problem, while the type is aliased, the possible values are still in the unit2, you don't get them unqualified without explicitly uses unit2. However, you can get them qualified:
Code: Pascal  [Select][+][-]
  1. AParam2: TypeEnum=TypeEnum.ruPixelsPerInch;
  2.  
will do.
That's a nice way to access the enum values. It makes me think that defining the enums in another unit and only importing the type could actually be a way to make sure the enum type is specified to avoid any ambiguity.  :) 
Conscience is the debugger of the mind

Leledumbo

  • Hero Member
  • *****
  • Posts: 8819
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Enum visibility across units
« Reply #10 on: May 23, 2025, 03:58:46 pm »
That's a nice way to access the enum values. It makes me think that defining the enums in another unit and only importing the type could actually be a way to make sure the enum type is specified to avoid any ambiguity.  :)
Yes, that would do the trick. I personally think scoped enum should be the default, but backward compatibility is something we cannot sacrifice.

MaxM74

  • New Member
  • *
  • Posts: 33
Re: Enum visibility across units
« Reply #11 on: May 26, 2025, 01:03:19 pm »
In program Project1 the function
Code: Pascal  [Select][+][-]
  1. function AFunction(AParam1: Single;
  2.                    AParam2: TypeEnum=ruPixelsPerInch;              //ERROR HERE
  3.                    AParam3: TypeRecord): Single;
is incorrect. The parameter(s) with default value(s) must be the last in the function declaration.

Then declaring parameters like Leledumbo did solves some other errors.

Yes, this is an example of the real Project Units.

Using it in this way will work

Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. uses Unit1;
  4.  
  5. var
  6.   aaa: TypeRecord;
  7.  
  8. function AFunction(AParam1: Single;
  9.                    AParam3: TypeRecord;
  10.                    AParam2: TypeEnum=TypeEnum.ruPixelsPerInch): Single;
  11. begin
  12.   Result:= AParam1+AParam3.dummyField;
  13. end;
  14.  
  15. begin
  16.   AFunction(3.1234, aaa);
  17. end.
  18.  

MaxM74

  • New Member
  • *
  • Posts: 33
Re: Enum visibility across units
« Reply #12 on: May 26, 2025, 01:08:04 pm »
It is not a language problem, but a scoping problem, programmer error.
Simply add the unit with the enum to the uses clause.

This is the same in other languages like C or C++.

The issue is: blame yourself.

So according to your reasoning every time you use an enum you should use scoping?
It would be more logical for the compiler to "see the constants" in every case.

I wanted to understand the deep reason.

Thaddy

  • Hero Member
  • *****
  • Posts: 17198
  • Ceterum censeo Trump esse delendam
Re: Enum visibility across units
« Reply #13 on: May 26, 2025, 03:49:06 pm »
I think the problem was solved by fixing the error. In that case you do not need scoping
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

 

TinyPortal © 2005-2018