From: cross@spitfire.i.gajendra.net   
      
   In article <10f30sp$1koun$4@dont-email.me>,   
   Arne Vajhøj wrote:   
   >On 11/12/2025 8:04 AM, Dan Cross wrote:   
   >> In article <10eok5t$2u3pu$1@dont-email.me>,   
   >> Arne Vajhøj wrote:   
   >>> Rewriting the business application from one   
   >>> memory safe language (Java, C#, Python, Pascal   
   >>   
   >> Given the `POINTER` type, consequent support for type-casting   
   >> pointers, and dynamic memory allocation, it's hard to understand   
   >> how VSI Pascal can be considered meaningfully memory safe in the   
   >> way that Rust or a managed language is.   
   >   
   >The US government considers Pascal a memory safe language.   
   >   
   >:-)   
      
   Have you seen the state of my government recently? :-(   
      
   >But I think you are right about it being a bit questionable.   
   >   
   >I consider the 3 biggest memory unsafe problems to be:   
   >* no out of bounds check for array index   
   >* allowing use of deallocated memory   
   >* memory leak due to memory never being deallocated   
      
   That's a decent starter list. I'd add not indirecting through   
   uninitialized pointers. The second two are phrased in terms   
   usually associated with dynamic memory allocation, but of course   
   returning a pointer to a stack-allocated variable is a form of   
   (2). And there are other problems, like trying to access and/or   
   rely on the specific values of padding bytes between aligned   
   data in a struct/record. Unconstrained pointer arithmetic, as   
   in C, is a huge area of concern.   
      
   I think it's debatable whether one does or should include some   
   notion of concurrency in one's definition of memory safety, but   
   it is an important area, so perhaps something about data races   
   should be included here, as well.   
      
   Anyway, my list is something like:   
      
   1. Accessing uninitialized data   
   2. Indirecting an invalid pointer (nil, uninitialized, dangling,   
    misaligned, or pointing to an invalid object)   
   3. Reading from/writing to memory before or after a valid object   
    (note: an array is a valid object, so as long as they are   
    also in the array, accessing the elements before or after   
    some element is ok)   
   4. Accessing an object after it is no longer in scope (note:   
    this includes dynamically scoped objects, such as those that   
    are heap allocated: so no use-after free, no double-frees,   
    and so on. But this also applies to lexically and block   
    scoped data, so no returning pointers to e.g. stack allocated   
    variables, and no assigning pointers to block scoped   
    variables and then indirecting them in the outer scope)   
   5. Invalid accesses inside of a valid object (e.g., misaligned   
    accesses, or trying to read padding bits, or partial reads   
    spanning multiple fields in some way that is not   
    architecturally valid)   
   6. Writing to read-only data   
   7. Unsynchronized accesses to read/write data   
      
   >Pascal only prevents the first not the other two.   
   >   
   >The other two are not as common in Pascal as in C,   
   >because dynamic memory allocation is not as common in   
   >Pascal as in C.   
      
   Pascal is certainly an improvement over (at least) C and   
   assembler languages in this domain: as I recall, it doesn't   
   support arbitrary pointer arithmetic, and arrays are properly   
   typed by including the array size in the type, and so on.   
      
   But there is a lot more in this domain that is very important   
   when considering overall memory safety that Pascal doesn't   
   address.   
      
   >I did a quick check in my code repo and I use dynamic   
   >memory allocation in 25% of my C pieces but only in   
   >0.5% of my Pascal pieces. I am just one out of   
   >millions so it is obviously anecdotal only, but pretty   
   >big difference ...   
   >   
   >Anyway 1 fixed + 2 not fixed but rare is not really   
   >fixed.   
   >   
   >So I think you are right and the US government is wrong.   
   >   
   >:-)   
      
   Yeah. That's about the long and short of it, unfortunately.   
      
   >I do not see a problem with the pointer type casts. If   
   >normal code is safe, then I think it is OK to have ways   
   >to workaround the safeness. Sometimes it is desirable   
   >and it is hopefully easy to identify usage of such   
   >constructs and require extra code review of such code.   
      
   You certainly need some kind of escape hatch to write some kinds   
   of programs. The issue is whether that's explicitly called out   
   as "unsafe" at the language level, and in Pascal, it's just not.   
   Trivially casting a pointer to an array of $n$ elements to an   
   array of $n+k$ elements (or a record, or something else) without   
   some indicator that there be dragons there isn't great.   
      
   Another issue is whether the language can prevent this   
   statically (that is, at compile time) or not. Consider   
   out-of-bounds array accesses; if I use some arbitrary integer to   
   index into an array, I am pretty much forced to check that at   
   runtime. On the other hand, if the language supports iterators,   
   then I can more or less guarantee at compile time that those are   
   valid.   
      
   Anyway, it's a big design space in languages, and one must admit   
   that safety in this dimension exists along some spectrum; from   
   trivially dangerous (C, assembler) to safe-by-default (Rust, Ada   
   etc). Pascal is somewhere in the middle.   
      
    - Dan C.   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|