Code that is excluded by conditional compilation still results in compile time errors

I am currently evaluating Elements / Oxygene with the aim of producing a .NET DLL whilst maintaining code compatibility with a Delphi Windows application.

I have found that I still get errors when compiling code that should be excluded by conditional compilation. For example:

type
{$IFDEF ELEMENTS}
  Str10 = String;
{$ELSE}
  Str10 = string[10];
{$ENDIF}

Results in errors:

(E5) Attributes are not allowed here
(E1) semicolon (;) expected, got open square bracket ([)
(E1) {$ENDIF} expected, got [
(E374) comma (,) or close square bracket (]) expected, got integer number
(E8) Invalid attribute type; only regular types allowed for attributes
(E279) No matching $IFDEF for $ENDIF

I have verified that the condition works properly when there are no syntax errors in the else clause. Could you please advise if this is the expected behaviour for conditional compilation and if there is any way to change this.

Elements version: 10.0.0.2293
Visual Studio 2017

Hi,

can you tell me which constructs the compiler fails on for you?

Our latest compiler checks undefined code too (but only for syntax errors, not for symbols), this to aid cross platform work.

When cases like this occur we decide on how to do them based on the issue, I can easily make it so an undefined [10] like above compiles; is there anything else?

Thatā€™s the only syntax issue I have found so far, however this behaviour is causing a lot of other errors in a codebase that currently compiles in Delphi .NET and Win32.
For example, when keywords such as type and const are used inside conditional compile statements.

type
  test1 = String;
{$IFNDEF DOTNET}
  test2 = String;
const
  test3 = 1;
{$ENDIF}

Result:

(E279) No matching $IFDEF for $ENDIF
(E1) {$ENDIF} expected, got const

Iā€™m also seeing errors relating to method implementations not being found, Iā€™m still looking into this but I think at least one case is when the IFDEF condition doesnā€™t match exactly, e.g. IFDEF around the declaration and the implementation is contained in the ELSE block of an IFNDEF.

youā€™ll want to use two separate IFDEFs for this:

type 
  test1 = String; 
  {$IFNDEF DOTNET} 
  test2 = String; 
  {$ENDIF}

{$IFNDEF DOTNET} 
const test3 = 1; 
{$ENDIF}

The way Elements handles ifdefs in v10 is that each IFDEF must be its own logical structure. you can nest an IFDEF in another code structure, or you can nest an other code structure inside Ean IFDEF, but you cannot have them ā€œoverlapā€, say, as below.

{$IFDEF X}
for x := 0 to 5 do begin
do stuff
{$ENDIF}
do more stuff
{$IFDEF X}
end;
{$ENDIF}

The for loop must be inside the ifdef or the ifdef must be inside the for loop. Thatā€™s because in Elements, IFDEFs become regular code structures (because you can also write then using ā€œif defined("X")ā€).

Thank you for the responses.

Is the original syntax issue with string[*] something that can be logged to get fixed?

Thanks, logged as bugs://80591

Yes. Let me log that. Do let us know if you have other issues though.

bugs://80591 got closed with status fixed.

@mh I suspect the ball has long since gone on this, but the new rules around $if are both confusing and problematic in many perfectly reasonable and common use cases (as I think evidenced by the number of problems/questions arising as a result of the change).

You mention in closing that this is ā€˜becauseā€™ you can also write them using if defined("X") ā€¦

I wonder if it is not too late to separate the two styles of conditional ?

Retain (or rather restore) the more flexible, previous behaviour of {$IF} and its brethren, but also introduce the more ā€˜programmaticā€™ style of if defined() behaviours for us in contexts where this is preferred.

I suspect that the use cases in which the new behaviour break/are problematic/cumbersome are predominantly in declarations, where the obvious differentiation between a directive vs the surrounding code (or rather, declaration) is arguably beneficial (code-like if statements would be very out of place here), rather than distraction or noise as might be felt to be the case of conditional code in implementation bodies.

Going back to the old behaviours for $IF's wouldnā€™t even break any code that had already been re-factored to accommodate the new rules.

Just a thought. :slight_smile:

1 Like

it is, because they are essentially the same thing. Elements IFDEF engine is not/no longer a C macro pre-processor but a deeply integrated part of the code structure in the compiler.

I havenā€™t yet seen a case that could not be worked around (resulting in cleaner IFDEFing in the process), or was a legitimate bug that we could/can fix.