[fpc-devel] 019605: Safety check for "const s: string" (similar to Range or Overflow checks)

Martin lazarus at mfriebe.de
Thu Jun 23 20:59:15 CEST 2011

It may be easier to discuss here.

* First it needs to be decided, if such a check in itself (ignoring any 
obstacles in it's implementation) has a chance to be accepted at all.
If such a check is not wanted (even if implementation were trivial), 
then well that's it.

* If it could be accepted as a feature (request), then I understand it 
may still be open for very long, as there is no guarantee, that anyone 
will do it.

* Implementation

On top of what I already wrote on mantis. I believe my initial idea can 
be further simplified.

Given:  procedure Foo(const s1, s2: string);

1) On entering of Foo:
- Foo needs a numeric temp variable for each passed in ref-counted const 
- The current ref count of each such param is stored in that list of 
temp vars
       for each sx in [s1, s2] do "tmp_rc[sx] := refcnt(sx)"
- The ref-count of each param is increased
   There is no need to check if s1=s2; if so then the ref-count of both 
of them will have increased by 2
       for each sx in [s1, s2] do "refcnt(sx) := refcnt(sx) + 1"
- The temp vars are updated, to become the difference between the 
original, and the new recount
       for each sx in [s1, s2] do "tmp_rc[sx] := refcnt(sx) - tmp_rc[sx]"

2) On exit, all the tep ref counts are decreased
       for each sx in [s1, s2] do "refcnt(sx) := refcnt(sx) - 1"
No ref count is allowed to become less than 1.
If any refcount goes less than 1, than this is an error.

  On any statement inside Foo, that adds a ref count to any Sx ("other 
:= s1"), the refcount of this sx has to be checked before the statement
       if  refcnt(sx) <= tmp_rc[sx]  then error
       other := sx
This way, if at any time, all non-temporary ref counts where gone, they 
can not be re-added ever again

It still requires, that, if any such param is passed to another 
procedure, that will accept it as const param, then all temp ref-counts 
must be removed.
- That is only, if the called procedure, is compiled with the flag, and 
adds it-s own temp refcnts
- If the called procedure is not compiled with the flag, then they must 
be kept.
Otherwise check "3" will not hold in a nested call.

In order do to such tmp-ref-cnt removal for selected params only, one 
would have to check for equality of multiply passes const param again. 

It might be easier, if a procedure
   procedure Foo(const s1, s2: string);
when compiled with the check-flag, wll have some hidden extra param
procedure Foo(const s1, s2: string; tmp_ref_cnt_s1, tmp_ref_cnt_s2: 

They contain the count of already added tmp ref-cnts ("tmp_rc[sx] "); or 
zero. This can then be use to check for the correct value, in point "3".

More information about the fpc-devel mailing list