---
minutes: 15
---

# Different semantics

<!-- mdbook tests skipped because its builds do not link libc -->

```rust,editable,ignore
use std::ffi::{CStr, c_char};
use std::time::{SystemTime, SystemTimeError, UNIX_EPOCH};

unsafe extern "C" {
    /// Create a formatted time based on timestamp `t`.
    fn ctime(t: *const libc::time_t) -> *const c_char;
}

fn now_formatted() -> Result<String, SystemTimeError> {
    let now = SystemTime::now().duration_since(UNIX_EPOCH)?;
    let seconds = now.as_secs() as i64;

    // SAFETY: `seconds` is generated by the system clock and will not cause
    // overflow
    let ptr = unsafe { ctime(&seconds) };

    // SAFETY: ctime returns a pointer to a preallocated (non-null) buffer
    let ptr = unsafe { CStr::from_ptr(ptr) };

    // SAFETY: ctime uses valid UTF-8
    let fmt = ptr.to_str().unwrap();

    Ok(fmt.trim_end().to_string())
}

fn main() {
    let t = now_formatted();
    println!("{t:?}");
}
```

<details>

Some constructs that other languages allow cannot be expressed in the Rust
language.

The `ctime` function modifies an internal buffer shared between calls. This
cannot be represented as Rust’s lifetimes.

- `'static` does not apply, as the semantics are different
- `'a` does not apply, as the buffer outlives each call

</details>
