Recent

Author Topic: SAFE mode for FPC  (Read 10731 times)

serbod

  • Full Member
  • ***
  • Posts: 142
SAFE mode for FPC
« on: January 13, 2017, 09:27:41 am »
Do FPC have possibility to enable "SAFE" mode, where all runtime checks enabled and any potentially risky syntax and features is disabled (produce error instead of warning)? So, compiled code will be not most efficient, but most failproof.

For example, disabled and forbidden:
- unsafe typecasting
- untyped variables, parameters, pointers and pointer arithmetics
- low-level memory manipulation routines
- unwrapped shared library functions calls
- uninitialized variables
- undefined function result
- calling constructor from variables (obj := obj.Create)
- usage of some classes in library initialization/finalization sections (TThread, TCriticalSection, ..)
- write to inherited properties in constructor
- write to global variables in class methods

Also, some features is forced:
- range, I/O, stack overflow, memory checking
- variables initialization to default
- smart pointers (with refcounting)
- unspecified modifier (const/var/val) warning for string, array, record parameters
« Last Edit: January 16, 2017, 11:09:34 am by serbod »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: SAFE mode for FPC
« Reply #1 on: January 13, 2017, 10:22:00 am »
ppcjvm ? :-)

serbod

  • Full Member
  • ***
  • Posts: 142
Re: SAFE mode for FPC
« Reply #2 on: January 13, 2017, 11:59:40 am »
ppcjvm ? :-)
yes, something like that, but for native compilation

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: SAFE mode for FPC
« Reply #3 on: January 13, 2017, 02:11:51 pm »
No there is no such thing. For starters, the native compilation is not a safe language to begin with.

Your list is also a mix of runtime and compiletime checks.

For compiletimechecks, there is a setting to halt on any warning. One could argue though if FPC's warning/hint algorithms are foolproof enough for that.

For runtime checks, you can enable several parts of those (unsafe typecasting of classes, seeding uninitialized variables with random data etc)

I think things like  usage of some classes in library initialization/finalization sections (TThread, TCriticalSection, ..) are more something for static code inspectors, not for the compiler.

There are several products and services for Delphi, maybe check that out.

serbod

  • Full Member
  • ***
  • Posts: 142
Re: SAFE mode for FPC
« Reply #4 on: January 13, 2017, 03:59:19 pm »
It useful not only for starters, but for anyone, who need extra reliability and don't want to shoot in the foot occasionaly.

I think, it can be done with preprocessor directives, like that:
Code: Pascal  [Select][+][-]
  1. {$IF MODE SAFE}
  2.   {$RANGECHECKS ON}
  3.   {$OBJECTCHECKS ON}
  4.   {$IOCHECKS ON}
  5.   {$CHECKPOINTER ON}
  6.   {$GOTO OFF}
  7.   ....
  8. {$ENDIF}

and mark some exported routines as @unsafe

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: SAFE mode for FPC
« Reply #5 on: January 13, 2017, 04:55:03 pm »
It useful not only for starters, but for anyone, who need extra reliability and don't want to shoot in the foot occasionaly.
FPC RTL shoot my foot with {$rangechecks on}

Here's the story:
On fpc 2.6.4 socket function htonl is declared (/rtl/inc/socketsh.inc) like this:
Code: Pascal  [Select][+][-]
  1. function htonl( host : longint):longint; inline;
  2.  
On fpc 3.0.0 socket function htonl is declared (packages/rtl-extra/src/inc/socketsh.inc) like that:
Code: Pascal  [Select][+][-]
  1. function htonl( host : cardinal):cardinal; inline;
  2.  
(the later use of unsigned integer makes more sense, if you ask me).

However, compiling the project with {$rangechecks on} caused me a range check error on 2.6.4
I'm storing address as unsigned 32 integer.
I saw the type declaration of "longint" and added the type casting to longint.
Code: Pascal  [Select][+][-]
  1.   htonl ( longint(myaddr));
After that i compiled the same code on 3.0.0. and it started throwing range checks at me.

The worse thing, is that not every ip address would cause the range check error.

Eventually I ended up adding
Code: Pascal  [Select][+][-]
  1. {$rangechecks off}
at the begging of the unit.


Yeah, I could probably write my own htonl() wrapper, that would do a proper casting, depending on compiler (RTL) version... but...
this is my target practice experience :)

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: SAFE mode for FPC
« Reply #6 on: January 13, 2017, 05:03:20 pm »
Seems rather SAFE to me,when a compiler finds an obvious error.....
Specialize a type, not a var.

serbod

  • Full Member
  • ***
  • Posts: 142
Re: SAFE mode for FPC
« Reply #7 on: January 16, 2017, 08:13:06 am »
Seems rather SAFE to me,when a compiler finds an obvious error.....

Some errors can't be autodetected from sources - array bounds, invalid pointers, access to destroyed objects, wrong typecast, wrong record alignment.. It's shame, that for 15-20 years of language developmant and usage, it still don't have any protection from routines, that can cause random critical runtime errors. Smart pointers for objects by default can solve most casual troubles. In 90'th with limited computing resources, extra runtime checks was burdening, but now it's not a problem even for pocket devices. Difference in performance between debug and release builds is unnoticable.

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: SAFE mode for FPC
« Reply #8 on: January 16, 2017, 08:35:38 am »
That's apples and pears and looks like you spend too much comparing with Java (definitely not with C++, that's worse).
BTW one really SAFE option that I do not see here yet, is compiling with -Sew . Treat warnings as errors. Or even -Sewhn and solve everything.
« Last Edit: January 16, 2017, 08:41:25 am by Thaddy »
Specialize a type, not a var.

serbod

  • Full Member
  • ***
  • Posts: 142
Re: SAFE mode for FPC
« Reply #9 on: January 16, 2017, 09:21:32 am »
That's apples and pears and looks like you spend too much comparing with Java

I don't like Java and don't use it. I don't care, if C++ still shoot in legs and loving it.

I just tired to alweys keep in mind, that some casual things in Pascal is surprisingly dangerous, and better not use them or use with extra cautions.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: SAFE mode for FPC
« Reply #10 on: January 16, 2017, 09:39:51 am »
Sounds like you simply want a preconfigured build mode in Lazarus. There is no need to do this in compiler, making managing large sets of settings and switching easily between them is a job for either the IDE, or requires the ability to write cmdline scripts yourself.

But as said, the main problems is that you heap too many different (runtime and compiletime) things together, moreover some of the compiletime checks (like variable not initialized etc) must be magnitudes more reliable to make it practical.




serbod

  • Full Member
  • ***
  • Posts: 142
Re: SAFE mode for FPC
« Reply #11 on: January 16, 2017, 10:13:31 am »
Sounds like you simply want a preconfigured build mode in Lazarus.

Yes, something obviously simple, like predefined DEBUG mode. But it also need some support from compiler and standard library.

Handoko

  • Hero Member
  • *****
  • Posts: 5129
  • My goal: build my own game engine using Lazarus
Re: SAFE mode for FPC
« Reply #12 on: January 16, 2017, 10:16:00 am »
Hello serbod, I don't mean to discourage you. Actually I like the idea of safe mode. But some may not agree with the things listed in your example.

untyped variables
Did you also mean untyped parameters? It can be useful sometimes. For example, I write module to write and load block data without fixed size from/to files and TMemoryStream. Using untyped parameters seems good and easier for me as long as I understand how to safely use untyped parameters.

uninitialized variables
I know uninitialized variables can be dangerous. But if we initialized all variables it will be decrease the performance, I know nowadays computers are fast. But I follow my style: initialized the variables only when it is going to be used.

range check
I always disable range check, I enable it only when for testing certain things. The last time I remember, enabling range check will slow the performance significantly. I don't say my codes are free from range check errors, but I always choose the data type properly before I use it and I always manually make sure the variable size is large enough to store the calculation values.

io check
Now I never enable it, the last time I use it was learning programming many years ago. I think it will be good if the error is caught by programmer rather than the software/compiler/computer? I mean will it better if the programmer write better code by using ioresult, isn't it?

stack overflow check
Do we still need it? Maybe. But I remember I used it when programming on 8-bit machine for DOS using Turbo Pascal 5.5. Now we're using 32 even 64 bit, do we now still have stack overflow issue?

I believe we usually learn a lot from errors. If we are overprotected, not much we will learn. By making the compiler do a lot of things to protect and to limit programmer to do certain things, it won't be good.

I don't mean to against your idea, but from experienced programmers' view point, it doesn't sound too good. It maybe good for novice programmers but I doubt it, because overprotected will make them learn less, in the future they won't know how to manipulate low-level memory, they can't prevent io and range problem manually.

Last words, safe mode is a nice feature to put on FPC (or Lazarus). But the problems are what items should put into the list and who will write this feature.

It's only my 2 cents, some may agree or not with me.
« Last Edit: January 16, 2017, 10:25:11 am by Handoko »

serbod

  • Full Member
  • ***
  • Posts: 142
Re: SAFE mode for FPC
« Reply #13 on: January 16, 2017, 11:02:28 am »
Hello serbod, I don't mean to discourage you. Actually I like the idea of safe mode. But some may not agree with the things listed in your example.

I agree with all that arguments. But if you notice, I don't propose disable inline assembler in safe mode. I just forgot, when I uses it, and doubt, that will sometime use again. =)

Same i can say for untyped variables and parameters. They can be useful for deep optimizations, but not needed in casual work. Stack/range/io checks is unnoticable for GUI and database application, where most runtime code is optimized pre-built libraries. But runtime crash errors is very noticable and very hard to find in sources.

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: SAFE mode for FPC
« Reply #14 on: January 16, 2017, 11:12:00 am »
Hello serbod, I don't mean to discourage you. Actually I like the idea of safe mode. But some may not agree with the things listed in your example.

untyped variables
Did you also mean untyped parameters? It can be useful sometimes. For example, I write module to write and load block data without fixed size from/to files and TMemoryStream. Using untyped parameters seems good and easier for me as long as I understand how to safely use untyped parameters.
Yes, pointer casts, variants and array of consts are very useful when you know what you are doing....
Quote
uninitialized variables
I know uninitialized variables can be dangerous. But if we initialized all variables it will be decrease the performance, I know nowadays computers are fast. But I follow my style: initialized the variables only when it is going to be used.
initializing a variable does not cost too much performance. Note global variables are ALWAYS initialized. Just stack based variables need initialization. There's the Default() intrinsic for that, nowadays.
Quote
range check
I always disable range check, I enable it only when for testing certain things. The last time I remember, enabling range check will slow the performance significantly. I don't say my codes are free from range check errors, but I always choose the data type properly before I use it and I always manually make sure the variable size is large enough to store the calculation values.
I ALWAYS have rangechecks on during debugging. I ALWAYS resolve all related warnings and hints. It is of off in release mode
Quote
io check
Now I never enable it, the last time I use it was learning programming many years ago. I think it will be good if the error is caught by programmer rather than the software/compiler/computer? I mean will it better if the programmer write better code by using ioresult, isn't it?
I personally use  {$I-} a lot and process the IOResult error codes. Especially if I can avoid pulling in exception handling. Much faster and just as safe.
Quote
stack overflow check
Do we still need it? Maybe. But I remember I used it when programming on 8-bit machine for DOS using Turbo Pascal 5.5. Now we're using 32 even 64 bit, do we now still have stack overflow issue?
Yes, we still need it, because cocky programmers like recursion ;) And multi-threading :)
Quote
I believe we usually learn a lot from errors. If we are overprotected, not much we will learn. By making the compiler do a lot of things to protect and to limit programmer to do certain things, it won't be good.

I don't mean to against your idea, but from experienced programmers' view point, it doesn't sound too good. It maybe good for novice programmers but I doubt it, because overprotected will make them learn less, in the future they won't know how to manipulate low-level memory, they can't prevent io and range problem manually.

Last words, safe mode is a nice feature to put on FPC (or Lazarus). But the problems are what items should put into the list and who will write this feature.

It's only my 2 cents, some may agree or not with me.

I more or less agree. What Marco wrote makes sense. Personally I like a very strict debug mode for very sensitive code. And it is definitely possible to create such a debug mode already.
If programmers, especially beginners, would solve all hints and warnings their code would be 90% better. There's a reason that the compiler itself is compiled with -Sew
« Last Edit: January 16, 2017, 11:15:14 am by Thaddy »
Specialize a type, not a var.

 

TinyPortal © 2005-2018