Groups | Search | Server Info | Keyboard shortcuts | Login | Register


Groups > comp.os.vms > #378187

Re: Unsafe code blocks

From cross@spitfire.i.gajendra.net (Dan Cross)
Newsgroups comp.os.vms
Subject Re: Unsafe code blocks
Date 2025-11-19 16:02 +0000
Organization PANIX Public Access Internet and UNIX, NYC
Message-ID <10fkpme$1dj$1@reader2.panix.com> (permalink)
References <10f4oi1$25lkk$2@dont-email.me> <10fbc6h$4hb$1@reader2.panix.com> <10fig0p$1n41a$2@dont-email.me>

Show all headers | View raw


In article <10fig0p$1n41a$2@dont-email.me>,
Arne Vajhøj  <arne@vajhoej.dk> wrote:
>On 11/15/2025 9:16 PM, Dan Cross wrote:
>>> Also note the availability of the 'Valid attribute to make sure that what
>>> is in the variable after the unsafe conversion is actually a valid value.
>> 
>> Sum types make this trivial:
>> 
>>      impl SomeType {
>>          fn try_from(i: i32) -> Option<Self> {
>>              // if valid, return `Some(whatever`),
>>              // else return `None`.
>>          }
>>      }
>(assuming Option in Rust is what it is in other languages)
>
>Option and Ada Valid are somewhat different.
>
>Option is a way for a function/method to either return
>a value or return the fact that there is no value.
>
>A much better way to do that than traditional
>return null or -1 or whatever to indicate there
>is no value.
>
>Ada valid attribute is a runtime check on the result from
>an unsafe conversion to see if it meets the constraints
>of the data type.

I'm afraid this misses the point.

If a language supports sum types, then general solutions like
`Option` or `Result` types can be employed to represent the
return type of the conversion operation.  If the conversion is
invalid, then one returns `None` (or, perhaps, the `Err` variant
of a `Result` if one wants to capture what the actual failure
was).  That is, the conversion operation itself subsumes the
functionality of the valid attribute, and both the value and
whether the conversion was valid are represented in the return
type.

Again, taking Rust just as an example, there is a standard way
to represent such conversions; the `TryFrom` trait (and it's
dual, `TryInto`).  Consider this silly example problem: I have a
type representing colors; perhaps the only colors I care about
are Red, Green, and Blue. I can label these with integers, say
1, 2 and 3, and I can represent this in Rust using an
enumeration.

Now further suppose that I have a file of 8-bit bytes that
contain the (raw, integral) representation of these color
values; I'd like to convert these into proper objects of the
enumeration type, but of course, not all 8-bit byte values
represent valid colors, so the proper tool in this case is
`TryFrom`.  Note, however, that converting back, from a color to
its 8-bit value, is _always_ valid, so I just use `From` in that
case (which also, conveniently, gives me `into`).

Here's the code:

```rust
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum Colors {
    Red = 1,
    Green = 2,
    Blue = 3,
}

impl TryFrom<u8> for Colors {
    type Error = String;
    fn try_from(raw: u8) -> Result<Self, Self::Error> {
        match raw {
            1 => Ok(Self::Red),
            2 => Ok(Self::Green),
            3 => Ok(Self::Blue),
            _ => Err(format!("unsupported value '{raw}'")),
        }
    }
}

impl From<Colors> for u8 {
    fn from(color: Colors) -> u8 {
        color as u8
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn try_from_raw() {
        assert_eq!(Colors::try_from(1), Ok(Colors::Red));
        assert_eq!(Colors::try_from(2), Ok(Colors::Green));
        assert_eq!(Colors::try_from(3), Ok(Colors::Blue));
        assert_eq!(Colors::try_from(0), Err("unsupported value '0'".into()));
    }

    #[test]
    fn from_clor() {
        assert_eq!(u8::from(Colors::Red), 1);
        assert_eq!(u8::from(Colors::Green), 2);
        assert_eq!(u8::from(Colors::Blue), 3);
    }
}
```

Note the unit tests.  Note also, that, as a result of the way
that the conversion is structured, as aided by the return type,
the conversion operation itself is safe.

Of course, this example is trivial, but the same principle
applies for more comple conversions as well, including unsafe
conversions.

Further, by localizing the unsafety inside of the conversion,
and using a return type that can represent failure, one can
construct a _safe_ interface to do _unsafe_ conversions.
Consider a hypothetical in-place conversion from an array of
bytes to a string type that is guaranteed to contain only valid
UTF-8 sequences, such as a Rust `&str`.  This is an `unsafe`
operation, since it relies on the program to assert that the
byte array contents are valid UTF-8.  But, my conversion
function can probe the input byte sequence for validity, and
return `Err` if an invalid sequence is found, otherwise it can
do an (unsafe) conversion and return that in an `Ok`.  This is
fine, since the conversion function itself enforces the
invariants required by the type.

In contrast, `Valid` is easy to misuse, primarily by not using
it at all, in which case you run the risk of raising a runtime
exception, or just having an incorrect program.  With either
`Option` or `Result`, you are forced to contend with the error
case.  The programmer can't forget to check.

Finally, `Valid` is very limited in its applicability: it can
only be used with scalar types.  At least in Rust, `Option` and
`Result` are generic over essentially arbitrary types.

Put another way, if the language supports something like an
`Option` type, then there is no need for a special-case facility
like Ada's `Valid` attribute.

	- Dan C.

Back to comp.os.vms | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

Unsafe code blocks Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2025-11-13 14:04 +0000
  Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-13 15:44 -0500
  Re: Unsafe code blocks Marc Van Dyck <marc.gr.vandyck@invalid.skynet.be> - 2025-11-14 12:14 +0100
    Re: Unsafe code blocks John Reagan <johnrreagan@earthlink.net> - 2025-11-14 11:47 -0500
      Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-14 14:02 -0500
        Re: Unsafe code blocks Marc Van Dyck <marc.gr.vandyck@invalid.skynet.be> - 2025-11-17 09:25 +0100
          Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-17 14:58 -0500
            Re: Unsafe code blocks Chris Townley <news@cct-net.co.uk> - 2025-11-17 20:11 +0000
              Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-17 15:47 -0500
            Re: Unsafe code blocks cross@spitfire.i.gajendra.net (Dan Cross) - 2025-11-18 13:10 +0000
      Re: Unsafe code blocks Lawrence D’Oliveiro <ldo@nz.invalid> - 2025-11-14 19:32 +0000
    Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-14 13:55 -0500
      Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-14 20:00 -0500
        Re: Unsafe code blocks Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2025-11-17 18:56 +0000
          Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-17 14:22 -0500
  Re: Unsafe code blocks cross@spitfire.i.gajendra.net (Dan Cross) - 2025-11-16 02:16 +0000
    Re: Unsafe code blocks Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2025-11-17 19:22 +0000
      Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-17 14:55 -0500
        Re: Unsafe code blocks Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2025-11-17 20:33 +0000
          Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-17 15:55 -0500
      Re: Unsafe code blocks cross@spitfire.i.gajendra.net (Dan Cross) - 2025-11-18 12:54 +0000
    Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-18 14:04 -0500
      Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-18 14:07 -0500
        Re: Unsafe code blocks cross@spitfire.i.gajendra.net (Dan Cross) - 2025-11-19 16:12 +0000
          Re: Unsafe code blocks Michael S <already5chosen@yahoo.com> - 2025-11-19 19:29 +0200
            Re: Unsafe code blocks cross@spitfire.i.gajendra.net (Dan Cross) - 2025-11-19 19:00 +0000
          Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-19 12:41 -0500
            Re: Unsafe code blocks cross@spitfire.i.gajendra.net (Dan Cross) - 2025-11-19 18:19 +0000
              Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-19 14:21 -0500
                Re: Unsafe code blocks cross@spitfire.i.gajendra.net (Dan Cross) - 2025-11-19 19:49 +0000
      Re: Unsafe code blocks cross@spitfire.i.gajendra.net (Dan Cross) - 2025-11-19 16:02 +0000
        Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-19 20:26 -0500
          Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-19 20:31 -0500
          Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-19 21:32 -0500
          Re: Unsafe code blocks cross@spitfire.i.gajendra.net (Dan Cross) - 2025-11-20 11:54 +0000
            Re: Unsafe code blocks Arne Vajhøj <arne@vajhoej.dk> - 2025-11-20 19:18 -0500
              Re: Unsafe code blocks cross@spitfire.i.gajendra.net (Dan Cross) - 2025-11-21 03:03 +0000

csiph-web