Lazarus

Free Pascal => General => Topic started by: 440bx on November 10, 2018, 01:12:36 am

Title: are compound conditional directives supposed to work ?
Post by: 440bx on November 10, 2018, 01:12:36 am
Hello,

I was reading the following wiki page
http://wiki.freepascal.org/Conditional_compilation (http://wiki.freepascal.org/Conditional_compilation)
which as an example shows:
Code: Pascal  [Select]
  1. {$IFDEF BLUE AND $IFDEF RED} Form1.Color := clYellow; {$ENDIF}

I needed something like that but using or instead of "and".  I tried using "OR" in the conditional and it didn't work (it is what it is.) 

My question is: was it supposed to work or is the Wiki page "not quite right" ?  better yet, is there some way to make such a construct work ? (without "helper" conditions and nested ifs)

Thanks. 

Full example below:
Code: Pascal  [Select]
  1. {$MODE OBJFPC}
  2.  
  3.  
  4. //
  5. // from:
  6. //
  7. // http://wiki.freepascal.org/Conditional_compilation
  8. //
  9. // {$IFDEF BLUE AND $IFDEF RED} Form1.Color := clYellow; {$ENDIF}
  10.  
  11.  
  12.  
  13. program ConditionalDirectives;
  14.  
  15. //{$define abc0123456789}
  16. {$define xyz0123456789}
  17.  
  18. uses
  19.   windows
  20.  
  21.   {$ifdef abc0123456789 or $ifdef xyz0123456789}
  22.   ,
  23.   sysutils
  24.  
  25.  {$endif}
  26.   ;
  27.  
  28. begin
  29.   // this works as expected
  30.  
  31.   {$ifdef abc0123456789}
  32.     writeln('abc is defined');
  33.   {$endif}
  34.  
  35.   // this works as expected
  36.  
  37.   {$ifdef xyz0123456789}
  38.     writeln('xyz is defined');
  39.   {$endif}
  40.  
  41.   //  but this does not work as the wiki page implies it should
  42.   //  the "or" seems to be ignored by the compiler
  43.  
  44.   {$ifdef abc0123456789 or $ifdef xyz0123456789}
  45.     writeln('either abc or xyz is defined');
  46.  
  47.     writeln('IntToHex 16 ', IntToHex(16, 6));
  48.   {$endif}
  49. end.
  50.  
Title: Re: are compound conditional directives supposed to work ?
Post by: Blaazen on November 10, 2018, 01:53:10 am
Code: Pascal  [Select]
  1. {$if defined(abc0123456789) or defined(xyz0123456789)}...code...{$endif}
Title: Re: are compound conditional directives supposed to work ?
Post by: 440bx on November 10, 2018, 02:13:33 am
That worked. Thank you Blaazen. 
Title: Re: are compound conditional directives supposed to work ?
Post by: engkin on November 10, 2018, 03:12:01 am
Also:
Code: Pascal  [Select]
  1.   {$IFNDEF BLUE AND $IFNDEF RED}
  2.   WriteLn('not Blue nor Red');
  3.   {$ELSE}
  4.   WriteLn('Blue or Red');
  5.   {$ENDIF}
Title: Re: are compound conditional directives supposed to work ?
Post by: 440bx on November 10, 2018, 03:59:17 am
Also:
Code: Pascal  [Select]
  1.   {$IFNDEF BLUE AND $IFNDEF RED}
  2.   WriteLn('not Blue nor Red');
  3.   {$ELSE}
  4.   WriteLn('Blue or Red');
  5.   {$ENDIF}

@Engkin

I'm under the impression that construct doesn't always work (of course, I could be mistaken).  I get that impression because in the example I posted,
Code: Pascal  [Select]
  1.  
  2. //{$define abc0123456789}
  3. {$define xyz0123456789}
  4.  
  5. { some code which doesn't matter here }
  6.  
  7.  
  8.   {$ifdef abc0123456789 or $ifdef xyz0123456789}
  9.     writeln('either abc or xyz is defined');
  10.  
  11.     writeln('IntToHex 16 ', IntToHex(16, 6));
  12.   {$endif}
  13. end.
  14.  
the writeln statements are not executed in spite of the fact that xyz0123456789 is defined.  In the same vein, the sysutils unit (see the original example) is not included.   When using that construction, it appears that the condition after the or is not evaluated and if the first condition is false then the entire condition is false even though it should be true because of the or and second condition being true.

Maybe I'm missing something... ?
Title: Re: are compound conditional directives supposed to work ?
Post by: Thaddy on November 10, 2018, 08:00:46 am
The only construct that is supposed to work is the example that Blaazen gave. The {$IF Defined()} and {$IF Declared()} type syntax was designed to have more complex  compound operations.
The {$IFDEF / $IFNDEF} syntax is not meant to support complex compound syntax without nesting. I would ask on the mailing list if the intended behavior has changed.
See https://www.freepascal.org/docs-html/current/prog/progse4.html#x135-1360002.1 and https://www.freepascal.org/docs-html/current/prog/progsu127.html#x140-1410002.4.1 which implies TurboPascal syntax for {$IFDEF} and family and that does NOT allow complex boolean operations. To my knowledge this behavior is not supposed to have changed.

[edit]
As I recall just now everything after the first name is assumed a comment.
Code: Pascal  [Select]
  1. program untitled;
  2. {.$define red}
  3. {$define blue}
  4. begin
  5. {$ifdef red or $ifdef blue} // everything after red is a comment
  6.   writeln ('read or blue');
  7. {$endif red or blue} // everything after red is a comment.
  8. end.
You probably have seen this style used in some libraries to document nested defines, mostly on the {$endif a comment}  parts.

In that light it is not a bug, but very confusing... A better example is:
Code: Pascal  [Select]
  1. program untitled;
  2. begin
  3. {$ifdef CPUARM this code is for arm only} // everything after CPUARM is a comment
  4.   writeln ('arm');
  5. {$endif arm specific code} // everything after endif is a comment.
  6. end.

I have submitted a request for update in the documentation #34532 in Mantis.
 
Title: Re: are compound conditional directives supposed to work ?
Post by: 440bx on November 10, 2018, 09:08:22 am
<cut>
The {$IFDEF / $IFNDEF} syntax is not meant to support complex compound syntax without nesting.
[edit]
<cut>
As I recall just now everything after the first name is assumed a comment.
Code: Pascal  [Select]
  1. program untitled;
  2. {.$define red}
  3. {$define blue}
  4. begin
  5. {$ifdef red or $ifdef blue} // everything after red is a comment
  6.   writeln ('read or blue');
  7. {$endif red or blue} // everything after red is a comment.
  8. end.
You probably have seen this style used in some libraries to document nested defines, mostly on the {$endif a comment}  parts.
Thanks Thaddy, that is helpful.

That Wiki article seems rather misleading.  It really gives the impression that the construct should work and makes no mention whatsoever of the alternate form Blaazen mentioned which does work as expected.

I agree with you that the documentation regarding compound conditionals needs a little "attention".

Thanks again.
Title: Re: are compound conditional directives supposed to work ?
Post by: Thaddy on November 10, 2018, 09:13:41 am
I will edit the wiki.
[edit] done. But it needs a complete rewrite which I will do later. For now I just corrected the mistakes and made a note.
Title: Re: are compound conditional directives supposed to work ?
Post by: creaothceann on November 10, 2018, 10:29:17 pm
You could also do something like this:

Code: [Select]
{$IFDEF BLUE}  {$DEFINE BLUE_OR_RED}  {$ENDIF}
{$IFDEF RED}   {$DEFINE BLUE_OR_RED}  {$ENDIF}
//...

{$IFDEF BLUE_OR_RED}
//...

{$ENDIF}

Dunno if that falls under your 'without "helper" conditions' condition...
Title: Re: are compound conditional directives supposed to work ?
Post by: 440bx on November 11, 2018, 12:50:52 am
Dunno if that falls under your 'without "helper" conditions' condition...
I do consider the additional definitions as "helpers" but I still appreciate your suggestion.  Thank you.
Title: Re: are compound conditional directives supposed to work ?
Post by: Thaddy on November 12, 2018, 02:58:03 pm
It is addressed by Michael and the documentation is updated with target 3.2.0. (!!)

I have started a complete rewrite of the wiki which will be finished in the next two days.
There were so many mistakes that I had to remove *the lot* because much of the example code wasn't even correct. Not only regarding this issue.
(I now use some of the old examples to explain what NOT to do... That bad...)
It was also overly verbose.
So for two days it is correct but not complete and after this wednesday I will ask to review the new entry here.
Title: Re: are compound conditional directives supposed to work ?
Post by: Windsurfer on November 12, 2018, 03:19:39 pm
Looking on the bright side, when Big Chimp and I added to the original wiki entry, it was almost impossible to find anything on the subject. Now we will have an expert update. Thanks Thaddy.
Title: Re: are compound conditional directives supposed to work ?
Post by: Thaddy on November 12, 2018, 04:53:39 pm
Looking on the bright side, when Big Chimp and I added to the original wiki entry, it was almost impossible to find anything on the subject. Now we will have an expert update. Thanks Thaddy.
I appreciate the effort, but code in the wiki should be tested before adding it. And that was not the case.
It was possible though to find - very implicit, I agree - its proper use. (in my mind, which is not accessible to any and all)
I would be much obliged if you read the wiki on wednesday and leave any comments.
Mistakes creep in quite easily... ;D And to be fair it wasn't all rubbish. My apologies for the correct parts but still not good enough to stay published.
The glass is always half full. 8-) O:-)
Title: Re: are compound conditional directives supposed to work ?
Post by: Windsurfer on November 12, 2018, 11:56:48 pm
Most of the contributions I have made as examples or in the wiki, have been the outcome of days of struggling to understand how to do things. I suspect that is also true for much of the older contributions from many contributors whose main career path was not as a programmer, but as an engineer or whatever.

When I saw your mention of Define, it was the first time that I remember seeing it. On the other hand, the LCL is becoming so good that I now rarely use conditional compilation statements.

This example code was taken from a project that compiled in 32bit Windows and 64bit Windows and Linux, which was a quite usual combination when it was written. Strangely, it compiled correctly for each with that conditional code, but not without it. 8 and 16 bit versions of any kind were simply not required and therefore irrelevant in the original context. If someone required that, surely a completely exhaustive example was not necessary because enough was given to provide an understanding.
Code: Pascal  [Select]
  1. var
  2.   MyFilesize:
  3.   {$ifdef Win32}
  4.     Cardinal
  5.   {$else}
  6.     int64
  7.   {$endif}

It is great to see things improving. Perhaps you could give a full example for comparison, but would the irrelevant parts not be removed by most programmers?

Title: Re: are compound conditional directives supposed to work ?
Post by: Thaddy on November 13, 2018, 08:09:15 am
It is great to see things improving. Perhaps you could give a full example for comparison, but would the irrelevant parts not be removed by most programmers?
I am currently writing and testing complete examples like:
Code: Pascal  [Select]
  1. var
  2.   MyFilesize:
  3.   {$ifdef Win32}
  4.     Cardinal
  5.   {$elseif Win64}
  6.     Qword
  7.   {$else}
  8.     {$error this code is for Microsoft Windows 32/64 Only}
  9.   {$endif}
Of course the above is no longer necessary:
Code: Pascal  [Select]
  1. var MyFileSize:NativeUint;
:D
Title: Re: are compound conditional directives supposed to work ?
Post by: Windsurfer on November 14, 2018, 10:24:21 am
Thanks Thaddy. I was not aware of NativeUint. I'll have to study fundamental types again, to see what else has happened.
Title: Re: are compound conditional directives supposed to work ?
Post by: marcov on November 14, 2018, 10:26:04 am
Please don't forget to add a documentation bug, so that the ignoring is added to the $ifdef and $ifndef lemmas of the documentation
Title: Re: are compound conditional directives supposed to work ?
Post by: Thaddy on November 14, 2018, 11:34:54 am
Michael had already done that. Target 3.2
Title: Re: are compound conditional directives supposed to work ?
Post by: Windsurfer on November 15, 2018, 08:32:22 am
The Free Pascal Programmers' Guide is here: https://freepascal.org/docs-html/prog/prog.html#progch1.html (https://freepascal.org/docs-html/prog/prog.html#progch1.html)
Title: Re: are compound conditional directives supposed to work ?
Post by: Thaddy on November 15, 2018, 09:29:56 am
The Free Pascal Programmers' Guide is here: https://freepascal.org/docs-html/prog/prog.html#progch1.html (https://freepascal.org/docs-html/prog/prog.html#progch1.html)
Yes, but the *fix* is in the documentation sources for the FPC 3.2.0 programmers guide and not yet on-line! You have to build the new documentation yourself for now, until 3.2.0 is released.
You can't simply refer to the 3.0.4 documentation. That won't be fixed.
Also note the documentation for 3.0.4. is actually correct, but the "comment" feature is simply omitted.

For documentation online goes the same as for the current release of the compiler itself: the current compiler is 3.0.4 and the current documentation is 3.0.4.
In the wiki that I will finish sometime today, I will make the point that this feature has always been there, at least since fpc 1.9

Stay put. I'll let you know when I am finished with the rewrite.
In the mean time try to build the new programmers guide from source... :D (warning: that is not easy the first time you try!)
Or read the raw TeX...