Recent

Author Topic: WARNINGS ON/OFF not working quite as expected.  (Read 1325 times)

440bx

  • Sr. Member
  • ****
  • Posts: 393
WARNINGS ON/OFF not working quite as expected.
« on: October 08, 2018, 07:43:11 pm »
Hello,

The compiler emits a warning when it encounters a "sizeof(anunitializedpointer^)" about the pointer not being initialized. 

To stop the compiler from emitting a warning in that case, turning WARNINGS OFF then back on after the statement should solve that problem and, it does BUT, after that, it will no longer warn if the pointer is _actually_ used without being initialized even though the warnings have been turned back on.

In the short sample program, in case 1, there really isn't any reason to emit a warning.  In case 2, there is good reason to emit a warning.  When the warning is suppressed for case 1, then no warning is given for case 2 (that's when it really should give a warning.)

Code: Pascal  [Select]
  1. {$MODE OBJFPC                        }
  2.  
  3. {$MODESWITCH     ADVANCEDRECORDS     }
  4. {$MODESWITCH     TYPEHELPERS         }
  5. {$MODESWITCH     ALLOWINLINE         }
  6. {$MODESWITCH     RESULT              }
  7. {$MODESWITCH     PROPERTIES          }
  8.  
  9. {$MODESWITCH     ANSISTRINGS-        }
  10. {$MODESWITCH     AUTODEREF-          }
  11. {$MODESWITCH     UNICODESTRINGS-     }
  12. {$MODESWITCH     POINTERTOPROCVAR-   }
  13.  
  14. {$LONGSTRINGS    OFF                 }
  15. {$WRITEABLECONST ON                  }
  16. {$TYPEDADDRESS   ON                  }
  17.  
  18.  
  19. {$define BadPointer}
  20.  
  21. program SizeofWarning;
  22.  
  23. var
  24.   SomePointer : PDWORD;
  25.  
  26. begin
  27.   // without the WARNINGS OFF directive the compiler warns about the use of
  28.   // SomePointer^ in sizeof.  It would be nice if it didn't, since the pointer
  29.   // really isn't being dereferenced.
  30.  
  31.  
  32. { case 1 }
  33.  
  34.   {$WARNINGS OFF}
  35.     writeln(sizeof(SomePointer^));    // generates spurious warning
  36.   {$WARNINGS ON}
  37.  
  38.   // {$WARNINGS ON} above doesn't seem to have the expected effect
  39.  
  40.   // the writeln below really deserves a warning but, none is generated
  41.  
  42. { case 2 }
  43.  
  44.   {$ifdef BadPointer}
  45.     writeln('you might get an exception when the next statement is executed');
  46.     writeln('Press any key to try your luck today.');
  47.     readln;
  48.  
  49.     writeln(SomePointer^);           // this should generate a warning because
  50.                                      // the variable is being dereferenced yet,
  51.                                      // it does not.
  52.   {$endif}
  53.  
  54.   writeln('Press any key to end this program');
  55.   Readln;
  56. end.
  57.  

it would be nice if the compiler was "aware" that dereferencing in a sizeof statement really isn't a dereference and, as such, does not merit a warning.

Thaddy

  • Hero Member
  • *****
  • Posts: 7228
Re: WARNINGS ON/OFF not working quite as expected.
« Reply #1 on: October 08, 2018, 08:56:17 pm »
Actually,what was the state of warnings? if it was off in the first place (because maybe a compiler switch instead of sourcecode directive) turning it on would be wrong.
As I explained before, you are using conditionals in a, let's say, funny way, using too much or assuming too little.
If you want full control over warnings there are several options, (I wrote the wiki part on those, have a look there http://wiki.freepascal.org/Turn_warnings_and_hints_on_or_off )
Simple example:
Code: Pascal  [Select]
  1. {$push} // don't assume on or off, but save state
  2. {$warnings off}
  3. // ... do something that normally throws a warning
  4. {$pop} // restore state: if it was off it stays off, if it was on, it's on again.
Or:
Code: Pascal  [Select]
  1. {$push}{$warn 5092 off}
  2. // .. Do something with uninitialized managed type .... would otherwise throw (5092) Variable "L" of a managed type does not seem to be initialized
  3. {$pop}

In Lazarus IDE and only in the Lazarus IDE there's a Lazarus specific macro option as well that doesn't work in other editors, like fp or geany or notepad++. See also the wiki.
That option is therefor not recommended.

To "fix" your code and introduce a bug:
Code: Pascal  [Select]
  1.   {$PUSH}{$WARN 5037 OFF}
  2.   // Warning: (5037) Variable "SomePointer" does not seem to be initialized
  3.   // generates a genuine warning otherwise: the content of SomePointer^ is not known...
  4.   // that's a bug!! The compiler will now assume this particular variable to be initialized... everywhere.
  5.     writeln(sizeof(SomePointer^));    
  6.   {$POP} // means further variable, but NOT this one will again raise to the warning

To really fix your code, initialize the content of SomePointer^ as the compiler told you.
Code: Pascal  [Select]
  1.   SomePointer^ := 0;
  2.   writeln(sizeof(SomePointer^));

Or
Code: Pascal  [Select]
  1.   writeln(SizeOf(PDWORD^));// now the second occurance will throw the warning..

Once you tell the compiler to ignore initialization for a variable it is internally registered as initialized, so the compiler will ignore further occurances.
That is the reason of your confusion the second time it occurs, but that is fully consistent compiler behavior. You marked it as ignore... Any further warning of the same kind for the same variable will be further ignored.
You can't "uninitialize" a variable very easily.... and what you did was telling the compiler, never mind, accept that I mean it is initialized, so that's what the compiler does....

I hope this is clear. I also hope it is clear that it is very dangerous to turn ALL warnings on or off as it can lead to a myriad of hard to find bugs.
But the compiler is consistent and above all: correct...
« Last Edit: October 08, 2018, 09:41:54 pm by Thaddy »
inline variables like in D10.3 are a bit like Brexit: if you are given the wrong information it sounds like a good idea. Every kid loves candy, but it makes you fat and your teeth will disappear.

Thaddy

  • Hero Member
  • *****
  • Posts: 7228
Re: WARNINGS ON/OFF not working quite as expected.
« Reply #2 on: October 08, 2018, 09:48:59 pm »
Note this goes for other things too:
Code: Pascal  [Select]
  1.   {.$packrecords 1}
  2. type
  3.   Tmyrecord = record
  4.   a:integer;
  5.   b:byte;
  6.   c:longint;
  7.   end;
  8.  
  9. var
  10.   // how is this packed?
  11.  {$packrecords 1}
  12.   d:TMyrecord;
  13. begin
  14.   writeln(SizeOf(d));
  15. end.
inline variables like in D10.3 are a bit like Brexit: if you are given the wrong information it sounds like a good idea. Every kid loves candy, but it makes you fat and your teeth will disappear.

440bx

  • Sr. Member
  • ****
  • Posts: 393
Re: WARNINGS ON/OFF not working quite as expected.
« Reply #3 on: October 08, 2018, 10:15:50 pm »
@Thaddy,

Your ability to generate and babble pointless, besides the point, nonsense seems to be the only natural talent you have. 

I have to give you credit for tirelessly developing it.

Thaddy

  • Hero Member
  • *****
  • Posts: 7228
Re: WARNINGS ON/OFF not working quite as expected.
« Reply #4 on: October 08, 2018, 10:18:33 pm »
You better pay attention. I just explained how and why. Sorry to mock you again about a clear lack of knowledge... :D (regarding your silly modeswitch dances....< >:D>)
For your reference, from globals.pas
Code: Pascal  [Select]
  1.     const
  2.        delphimodeswitches =
  3.          [m_delphi,m_class,m_objpas,m_result,m_string_pchar,
  4.           m_pointer_2_procedure,m_autoderef,m_tp_procvar,m_initfinal,m_default_ansistring,
  5.           m_out,m_default_para,m_duplicate_names,m_hintdirective,
  6.           m_property,m_default_inline,m_except,m_advanced_records,
  7.           m_array_operators];
  8.        delphiunicodemodeswitches = delphimodeswitches + [m_systemcodepage,m_default_unicodestring];
  9.        fpcmodeswitches =
  10.          [m_fpc,m_string_pchar,m_nested_comment,m_repeat_forward,
  11.           m_cvar_support,m_initfinal,m_hintdirective,
  12.           m_property,m_default_inline];
  13.        objfpcmodeswitches =
  14.          [m_objfpc,m_fpc,m_class,m_objpas,m_result,m_string_pchar,m_nested_comment,
  15.           m_repeat_forward,m_cvar_support,m_initfinal,m_out,m_default_para,m_hintdirective,
  16.           m_property,m_default_inline,m_except];
  17.        tpmodeswitches =
  18.          [m_tp7,m_tp_procvar,m_duplicate_names];
  19. {$ifdef gpc_mode}
  20.        gpcmodeswitches =
  21.          [m_gpc,m_tp_procvar];
  22. {$endif}
  23.        macmodeswitches =
  24.          [m_mac,m_cvar_support,m_mac_procvar,m_nested_procvars,m_non_local_goto,m_isolike_unary_minus,m_default_inline];
  25.        isomodeswitches =
  26.          [m_iso,m_tp_procvar,m_duplicate_names,m_nested_procvars,m_non_local_goto,m_isolike_unary_minus,m_isolike_io,
  27.           m_isolike_program_para,
  28.           m_isolike_mod];
  29.        extpasmodeswitches =
  30.          [m_extpas,m_tp_procvar,m_duplicate_names,m_nested_procvars,m_non_local_goto,m_isolike_unary_minus,m_isolike_io,
  31.           m_isolike_program_para,
  32.           m_isolike_mod];

The issue at hand is explained in depth. I hope it helped.
« Last Edit: October 08, 2018, 10:22:26 pm by Thaddy »
inline variables like in D10.3 are a bit like Brexit: if you are given the wrong information it sounds like a good idea. Every kid loves candy, but it makes you fat and your teeth will disappear.

440bx

  • Sr. Member
  • ****
  • Posts: 393
Re: WARNINGS ON/OFF not working quite as expected.
« Reply #5 on: October 08, 2018, 10:41:45 pm »
You better pay attention. I just explained how and why. Sorry to mock you again about a clear lack of knowledge... :D (regarding your silly modeswitch dances....< >:D>)
For your reference, from globals.pas
Code: Pascal  [Select]
  1.     const
  2.        delphimodeswitches =
  3.          [m_delphi,m_class,m_objpas,m_result,m_string_pchar,
  4.           m_pointer_2_procedure,m_autoderef,m_tp_procvar,m_initfinal,m_default_ansistring,
  5.           m_out,m_default_para,m_duplicate_names,m_hintdirective,
  6.           m_property,m_default_inline,m_except,m_advanced_records,
  7.           m_array_operators];
  8.        delphiunicodemodeswitches = delphimodeswitches + [m_systemcodepage,m_default_unicodestring];
  9.        fpcmodeswitches =
  10.          [m_fpc,m_string_pchar,m_nested_comment,m_repeat_forward,
  11.           m_cvar_support,m_initfinal,m_hintdirective,
  12.           m_property,m_default_inline];
  13.        objfpcmodeswitches =
  14.          [m_objfpc,m_fpc,m_class,m_objpas,m_result,m_string_pchar,m_nested_comment,
  15.           m_repeat_forward,m_cvar_support,m_initfinal,m_out,m_default_para,m_hintdirective,
  16.           m_property,m_default_inline,m_except];
  17.        tpmodeswitches =
  18.          [m_tp7,m_tp_procvar,m_duplicate_names];
  19. {$ifdef gpc_mode}
  20.        gpcmodeswitches =
  21.          [m_gpc,m_tp_procvar];
  22. {$endif}
  23.        macmodeswitches =
  24.          [m_mac,m_cvar_support,m_mac_procvar,m_nested_procvars,m_non_local_goto,m_isolike_unary_minus,m_default_inline];
  25.        isomodeswitches =
  26.          [m_iso,m_tp_procvar,m_duplicate_names,m_nested_procvars,m_non_local_goto,m_isolike_unary_minus,m_isolike_io,
  27.           m_isolike_program_para,
  28.           m_isolike_mod];
  29.        extpasmodeswitches =
  30.          [m_extpas,m_tp_procvar,m_duplicate_names,m_nested_procvars,m_non_local_goto,m_isolike_unary_minus,m_isolike_io,
  31.           m_isolike_program_para,
  32.           m_isolike_mod];

The issue at hand is explained in depth. I hope it helped.
As I said in the previous post... you don't get tired of babbling nonsense away.  If you could focus that dedication into learning about computer programming, you might eventually become decent at it.

ASerge

  • Hero Member
  • *****
  • Posts: 1004
Re: WARNINGS ON/OFF not working quite as expected.
« Reply #6 on: October 09, 2018, 03:01:00 am »
Let's take a shorter example:
Code: Pascal  [Select]
  1. {$APPTYPE CONSOLE}
  2. {$WARNINGS ON}
  3. var
  4.   SomePointer: PInteger;
  5. begin
  6.   // Bad to dereference a nil pointer!
  7.   Writeln(SomePointer^); // This line generates warning, it's OK
  8.   Writeln(SomePointer^); // But if you comment out the line above, THIS line generates a warning. Typically, warnings are not re-generated. This behavior is compatible with Delphi
  9.   Writeln(SizeOf(SomePointer^)); // It also generates a warning when the lines above are commented out, but should only generate a hint about the unused variable. I think this is a bug
  10.   Readln;
  11. end.

440bx

  • Sr. Member
  • ****
  • Posts: 393
Re: WARNINGS ON/OFF not working quite as expected.
« Reply #7 on: October 09, 2018, 05:22:40 am »
Typically, warnings are not re-generated. This behavior is compatible with Delphi
That's reasonable and useful since it doesn't drown the programmer in repeated warnings for the same thing.

It's unfortunate that the compiler's warning system doesn't realize that sizeof(apointer^) isn't actually dereferencing the pointer, which leads to a superfluous warning when the pointer isn't initialized and, no warning when the uninitialized pointer is used because it considers it a repetition, when it actually isn't one, since in one case the pointer isn't really dereferenced while it actually is dereferenced in the second case.

It would be nice (and useful) if the compiler could be made aware of the difference.

Thaddy

  • Hero Member
  • *****
  • Posts: 7228
Re: WARNINGS ON/OFF not working quite as expected.
« Reply #8 on: October 09, 2018, 05:58:27 pm »
Since a pascal compiler first evaluate use of the inner statement which is a reference to that pointer, it is unlikely that any Pascal compiler will solve your issue.
To me it is obvious, to some it may not. It is the programmer that decides to ignore warnings.
As this example shows, usually the compiler is right and the programmer is wrong. BTW this is not side effect: this is as intended.

Aside: do you understand now why your over-use and mis-use of compiler directives makes me laugh and running all over the floor before I can even reply to one of your questions?
I am not the only one... trust me... 8-) This is not about downgrading you, it is about you realizing you lack some knowledge as I do in some parts (but that is only since wikipedia.. :-X) , but not here...
« Last Edit: October 09, 2018, 06:02:58 pm by Thaddy »
inline variables like in D10.3 are a bit like Brexit: if you are given the wrong information it sounds like a good idea. Every kid loves candy, but it makes you fat and your teeth will disappear.

440bx

  • Sr. Member
  • ****
  • Posts: 393
Re: WARNINGS ON/OFF not working quite as expected.
« Reply #9 on: October 09, 2018, 06:17:05 pm »
Aside: do you understand now why your over-use and mis-use of compiler directives makes me laugh and running all over the floor before I can even reply to one of your questions?
Too bad it doesn't make you laugh enough to stay on the floor away from the keyboard.