Inconsistent behaviour from declared() conditional lazarus / 21-General ---------------------------------------------------------------------- MarkMLl · 2023-11-23 15:58 This is something that's been causing me problems for a couple of days, but I've only just started to see what's going on. If I use FPC 3.2.2 to compile two trivial test programs (testA.pas and testB.pas) with no special options: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program test; const{$if declared(test) }  test2= 'Is declared A';{$else            }  test2= 'Not declared A';{$endif             } begin  WriteLn(test2)end.  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program test; {$if declared(test) }const  test3= 'Is declared B';{$else            }const  test3= 'Not declared B';{$endif             } begin  WriteLn(test3)end.  then the results should be the same. But what I get is Code: [Select]$ ./testA Is declared A $ ./testB Not declared B What am I doing wrong? MarkMLl ---------------------------------------------------------------------- jamie · 2023-11-23 17:53 Fails on 3.0.4 too. So, this has been around for some time. However, I noticed Code-Tools in laz handles it just fine. I don't recall ever using "Declared" so I can't say. ---------------------------------------------------------------------- Bart · 2023-11-23 18:35 Quote from: MarkMLl on November 23, 2023, 04:58:32 pmWhat am I doing wrong? Probably nothing. Seems like a compiler bug. Same behaviour with fpc main (3.3.1-3157-g728be94328) File a bugreport? Bart ---------------------------------------------------------------------- ASerge · 2023-11-23 19:08 An interesting bug. While there was no section declaring variables or constants, the program name is considered undeclared. In the last example, you can add an insignificant declaration const A = 'A' to the beginning, just to make some kind of declaration - and everything will work as it should. ---------------------------------------------------------------------- MarkMLl · 2023-11-23 19:14 Thanks both for the 2nd and 3rd (and 4th) opinions. I'll wrestle with Gitlabs and try to find out why I can't get in. Possible xref to https://forum.lazarus.freepascal.org/index.php/topic, 65282.msg497345.html#msg497345 which is worrying since various people are apparently relying in declared() to check for an imported unit e.g. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   {$IF Declared(heaptrc)}  SetHeapTraceOutput('heaptrc.txt');  {$ENDIF}  However I've got rid of a couple more problems in my test code over the afternoon and it looks as though the real issue is the placement of "const"... and I'm not sure whether it is 100% reproducible or if it depends on the precise placement of the conditional in a unit. MarkMLl ---------------------------------------------------------------------- MarkMLl · 2023-11-23 19:21 Quote from: ASerge on November 23, 2023, 08:08:00 pmAn interesting bug. While there was no section declaring variables or constants, the program name is considered undeclared. In the last example, you can add an insignificant declaration const A = 'A' to the beginning, just to make some kind of declaration - and everything will work as it should. It's not just the program name, it appears to affect any test of whether a unit is declared and possibly more. I'll be putting up a more detailed test program tomorrow in the context of some other problems, but I was initially having problems with this Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i (* Uncomment no more than one of these uses clauses:                          *) //                              , LogicAnalyzer; {$define ANALYZER__:= LogicAnalyzer }//                              , LogicAnalyzer_Dynamic; {$define ANALYZER__:= LogicAnalyzer }                              , Analyzer_VcdCode; {$define ANALYZER__:= Analyzer_VcdCode } (* WARNING: if an inexplicable error is suddenly indicated in one of the lines  *)(* above, expect it to actually be on a line where the ANALYZER__ macro is      *)(* expanded.                                                                  *) // As of 3.2.2 it appears to be impossible to make a constant declaration// conditional on being inside a declared() block. Further investigation// suggests that it depends on whether the const (i.e. specifically that// reserved word) is or is not inside the conditional block. const  libraryName= '/usr/local/src/b5500- emulator/trunk/analyzer/libanalyzer_vcd.so'; {$if declared(LogicAnalyzer_Dynamic) }var  LogicAnalyzer: TLogicAnalyzer= nil;{$endif                              }  I think you can see from the comments where most of the afternoon went, but in fairness Sven has warned me about the macro issues before. But I really can't see an alternative... MarkMLl ---------------------------------------------------------------------- MarkMLl · 2023-11-23 21:47 Reported as https://gitlab.com/freepascal.org/fpc/source/-/issues/40541 Come back Mantis, all is forgiven :-( Since the bug report cites the test programs in this thread, is there any way of locking it against deletion while still allowing comments? MarkMLl ---------------------------------------------------------------------- runewalsh · 2023-11-23 22:21 I noticed a possibly similar bug in https://gitlab.com/freepascal.org/ fpc/source/- /blob/ea0b57f20bf9480e8285c71f98a5460d362b8ec3/tests/webtbs/tw13281.pp , where my guess is: declared() does not work before uses (nothing is used yet), and when const or other section is started, compiler behaves as if dummy uses was proceed, with implicit System, etc. The case with unit/program identifiers is probably different though. ---------------------------------------------------------------------- MarkMLl · 2023-11-23 22:39 Quote from: runewalsh on November 23, 2023, 11:21:35 pmI noticed a possibly similar bug in https://gitlab.com/freepascal.org/fpc/source/- /blob/ea0b57f20bf9480e8285c71f98a5460d362b8ec3/tests/webtbs/tw13281.pp , where my guess is: declared() does not work before uses (nothing is used yet), and when const or other section is started, compiler behaves as if dummy uses was proceed, with implicit System, etc. The case with unit/program identifiers is probably different though. That certainly sounds similar, but from what I've seen over the last couple of days I suspect that it's more an issue of splitting a section (nice COBOL term :-) over a declared() than anything to do with the uses statement. In fact I'd certainly hope that the maintainers will be checking for other problematic splits... Also- at least in my case- the problem was obfuscated by the fact that I was using a macro, so (a) FPC was inclined to report that a problem was at the point of macro definition rather than expansion and (b) the Lazarus IDE was having a hard time working out which reported problem merited being highlighted. Some problems are fun. This one wasn't, since the IDE was trying to tell me several different things none of which were really right. MarkMLl ---------------------------------------------------------------------- MarkMLl · 2023-11-24 13:39 Wrapping this one up for the moment, at least pending any comments from the devs. I think that it was actually the root cause of several problems I was experiencing. I find that I've had to add cthreads to the uses list of the library I was working on to prevent it crashing when called from a background thread, the funny thing was that when I tried that a couple of days ago it had no obvious effect so the compiler wasn't quite behaving as expected. MarkMLl