Recent

Author Topic: are compound conditional directives supposed to work ?  (Read 8093 times)

440bx

  • Hero Member
  • *****
  • Posts: 3944
are compound conditional directives supposed to work ?
« on: November 10, 2018, 01:12:36 am »
Hello,

I was reading the following wiki page
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.  
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: are compound conditional directives supposed to work ?
« Reply #1 on: November 10, 2018, 01:53:10 am »
Code: Pascal  [Select][+][-]
  1. {$if defined(abc0123456789) or defined(xyz0123456789)}...code...{$endif}
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: are compound conditional directives supposed to work ?
« Reply #2 on: November 10, 2018, 02:13:33 am »
That worked. Thank you Blaazen. 
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: are compound conditional directives supposed to work ?
« Reply #3 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}

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: are compound conditional directives supposed to work ?
« Reply #4 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... ?
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: are compound conditional directives supposed to work ?
« Reply #5 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.
 
« Last Edit: November 10, 2018, 08:50:22 am by Thaddy »
Specialize a type, not a var.

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: are compound conditional directives supposed to work ?
« Reply #6 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.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: are compound conditional directives supposed to work ?
« Reply #7 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.
« Last Edit: November 10, 2018, 11:47:22 am by Thaddy »
Specialize a type, not a var.

creaothceann

  • Full Member
  • ***
  • Posts: 117
Re: are compound conditional directives supposed to work ?
« Reply #8 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...

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: are compound conditional directives supposed to work ?
« Reply #9 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.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: are compound conditional directives supposed to work ?
« Reply #10 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.
« Last Edit: November 12, 2018, 03:01:16 pm by Thaddy »
Specialize a type, not a var.

Windsurfer

  • Sr. Member
  • ****
  • Posts: 368
    • Windsurfer
Re: are compound conditional directives supposed to work ?
« Reply #11 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.

Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: are compound conditional directives supposed to work ?
« Reply #12 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:-)
« Last Edit: November 12, 2018, 05:01:55 pm by Thaddy »
Specialize a type, not a var.

Windsurfer

  • Sr. Member
  • ****
  • Posts: 368
    • Windsurfer
Re: are compound conditional directives supposed to work ?
« Reply #13 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?


Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: are compound conditional directives supposed to work ?
« Reply #14 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
« Last Edit: November 13, 2018, 08:40:50 am by Thaddy »
Specialize a type, not a var.

 

TinyPortal © 2005-2018