Elements 10 Build Error within false conditional define: "class member expected but 'case' found"

conditional-define

(Matt Robertson) #1

I’m working to get our codebase compiling on Elements 10 - right now we’re stuck using 9.3.x because our code that compiles on 9.3.x generates over 10,000 build errors on 10.x. Our codebase is shared among Mac, Windows, iOS, and Android, and so we are using conditional defines to ignore non-Oxygene-compatible code, in order to avoid build errors. Based on the comment below, it seems that even these false conditional define blocks are required to be considered valid by the Elements compiler (please correct me if I’m wrong).

Here is one example of a small bit of code that’s generating an error.

{$if TARGET_RT_BIG_ENDIAN}

type
	wide = record
		case boolean of
			false:
				(hi:		SInt32;
				 lo:		UInt32);
			true:
				(int:	SInt64)
	end;

{$endif}

TARGET_RT_BIG_ENDIAN is not defined in the Android/Oxygene code, but attempting to compile generates this error

E12: Class member expected but ""case"" found


FPC Compatibility
Build error on using VAR param in a double-nested method
(marc hoffman) #2

Matt,

undefined code needs to be syntactically correct, yes. It can use identifiers (eg types, methods) that are unknown, but the general structure must be valid. I don’t believe we support (or ever did support) “case” in records — I assume the intent is to share this code with Delphi?


(Matt Robertson) #3

Thanks for the quick reply Marc - the goal is to share with FPC.


(marc hoffman) #4

Gotcha. I’ll have to check with Calro tomorrow what he thinks we can do there, given we don’t support this syntax nor, I believe, can support unions safely on all platforms. Maybe we can make the compile more forgiving for Delphi/FPC-only syntaxes, in undefined code for example.


(Matt Robertson) #5

Thanks Marc. Allowing unsupported syntax in non-applicable conditional directive blocks would be great.


(marc hoffman) #6

We’ll see what we can do.

Not that we’ll definitely not got back to allowing invalid code in inactive IFDEF sections. The reason is that its our new v10 conditional processing, the compiler must be able to / is able to hold the entire file structure in a single tree, for all conditions (eg ing you have a project IFDEFed for Android and iOS, say, in v9 there were two separate trees, as essentially each compiler looked at different pre-processed files. in v10, it can parse and hold one copy — which comes in handy inside the IDE, as well as when our cross-platform Gotham platform ships later next year).

What we can hopefully do is pretend-support well-known code structures we don’t actually support, if they are in sections that are always undefined when using Elements (such code in a define set only for FPC or Delphi)…


(Bartosz Antosik) #7

It is a pure coincidence that I have tried Oxygene today on a code that should also work on FPC. I was stunned by the fact that it tries to interpret sections excluded by compiler directives! And also in a small test it has lead to 3000 errors.

Please do something about it as it is a blocker for me from purchase of the license.

P.S.1 Is it possible to download evaluation of version 9.3 somewhere?
P.S.2 There is something on your documentation called Use Legacy Preprocessor but it seems gone from project options? Am I right? Can this be reactivated somehow?


(marc hoffman) #8

Yes, I’ll bring this up for discussion with the team tomorrow and we’ll see what we can do. Examples for what sort of code constructs you have that don’t “non-compile” would help us establish the scope for this.

Not right now, 9.3 is very old and it would not give a good evaluation experience at this time. that said:

It’s not exposed in the UI because it is not a documented/recommended option, but it is still there and you can activate it manually by adding <UseLegacyPreprocessor>True</UseLegacyPreprocessor> to your project file manually. This should “solve” the problem for you, and be a better way to evaluate Oxygene than going to back to 9.3.

Let me know ion this works for you; if not, I can upload a copy of 9.3 to your Personal Downloads, but I’d prefer if you can use Elements 10 .2351 and the above switch, if that works for you.

thanx,
marc


(Carlo Kok) #9

You can set that option <UseLegacyPreprocessor>True</UseLegacyPreprocessor> in the project file itself.

If you can give me samples of things that we don’t support (like the variant case above) I can take a look.


(Matt Robertson) #10

Wow this is fantastic. I had no idea that <UseLegacyPreprocessor>True</UseLegacyPreprocessor> existed. It looks like this should be enough to make it manageable to get my project building on Elements 10 for now.

@mh I set the project option to allow legacy “var” to True as you pointed out, and this cut the number of errors down from 10k+ to 62. Most of these seem to be mismatching of aliases. For example, in our project Str = String, but some procedures are defined with Str and implemented with String - this wasn’t a problem on 9.3 but is on 10. At this point I can sort through these and then build without <UseLegacyPreprocessor>True</UseLegacyPreprocessor> and get a manageable list of syntax exceptions for you guys.


(marc hoffman) #11

Yeah, v10 got stricter there, the interface and the implementation need to match exactly. IMHO that’s actually a good thing, as it promotes consistency and cleaner code.

Excellent!


(Matt Robertson) #12

Definitely so - I appreciate the change.


(Bartosz Antosik) #13

@mh @ck You see gentleman how much of a hassle the new behavior of conditional compilation can cause and how great joy is the discovery of <UseLegacyPreprocessor> is! :wink:

I will follow your request to show you constructs that cause errors in conditionally compiled code but I honestly think you should maybe reconsider this a bit. Like you had issue you had asked about elsewhere about conditionally defined uses clause:

uses
{$ifdef FPC}
  Classes,
  SysUtils,
  Types,
  Math;
{$else}
  System.Threading,
  System.Text;
{$endif}

First, you compile it you got:

(E1) {$ENDIF} expected, got ; at the line with Math;

and:

(E278) No matching $IFDEF for $ELSE exactly at the line with {$else}.

and:

(E3) "implementation" or interface section members (types or methods) expected

line below. You thing you got crazy, because you see {$else} and you are sure it is absolutely impossible to interpret code in this area. So you check whether project is OK and whether proper compiler is applied. It takes about a quarter. Then you think maybe conditional defines case is imposed? You change it. Nothing.

I have figured out, on my own, that I should use semi colon OUTSIDE of conditional clause but it took about three quarters and requires to carefully modify every single module!

Few lines below I find another example:

TSomeEvent = {$ifdef FPC} procedure {$else} delegate {$endif}(
    Sender: TObject; Reason: integer){$ifdef FPC} of object {$endif};

generates two even more confusing errors:

(E1) semicolon (;) expected, got open parenthesis at first line and
(E1) equals (=) expected, got colon (:) at the second.

Please, forgive me to say this, but it is crazy!

I really expect conditionally disabled code not to be interpreted! I understand there is some indication for this in the internal structure but it is highly confusing.

Precisely speaking you want me to redact the code twice in Oxygene and once in FPC. And the compiler is not helping but obstructing, because you have to watch what is going on in sections that you are used to watch in different circumstances (FPC). It is going to be highly distracting.


(Theo) #15

You can misuse the FPC macros to escape the strict Oxygene compiling for the FPC only code parts:

{$define --:=*/;}
{$define ++:=/*;}
{$if TARGET_RT_BIG_ENDIAN}
/*--
type
	wide = record
		case boolean of
			false:
				(hi:		SInt32;
				 lo:		UInt32);
			true:
				(int:	SInt64)
	end;
++*/
{$endif}

Oxygene will now see it as comment, while FPC sees it as code


(Bartosz Antosik) #17

Possibly. To me that would be even more confusing.


(Theo) #18

But at least it will compile in both, just a work-around the fact that Oxyxgene wants syntactical correct code in the {IF}s that are not compiled.


(Carlo Kok) #19

@baatro just to be clear; it DOES work with UseClassicPreprocessor right?


(Bartosz Antosik) #20

Yes it does!

But you know, there is this kind of tension when using “Legacy” flags. You feel like you do something wrong or start examining how old are you… Plus it’s hackery. :wink:


(Bartosz Antosik) #21

But it is very clever!


(Matt Robertson) #22

The macro hack is clever, but I have an existing code base of about a half million lines that uses conditional compilation extensively to allow for shared code among Mac, Windows, iOS, and Android (Oxygene). Everything works fine pre-Elements 10 but now I get about 8500 build errors with Elements 10. Adding the macro hack to every “error” location isn’t feasible. More importantly, the entire purpose of conditional compilation directives is to avoid problems like this.