That’s just a very bad API. You could do the same in Rust? There are nice C APIs that would use a nice struct that describes the timeout you want… eg GCD.
I'm not sure a struct is the right thing here in general. You often want an algebraic datatype.
What Rust calls an enum, but an enum with payloads. In C terms it would be a discriminated union.
In general it's a problem of sentinel values. Some languages let you abstract this - I think in Rust and C++ you can define an "intrusive optional" which is like optional but uses an invalid value pattern to store the not-present state. In memory it's the same as a sentinel value but the compiler forces you to unwrap it like an optional.
I'm not sure how well the 'forcing' works for Rust and C++. You can definitely do this kind of thing in dependently typed languages.
The type is akin to optional<int>. You can't add 5 to it, you have to dereference it first which crashes if it was null (0 or another chosen value).
Well, in Rust you would use pattern matching, which can't even crash.
In Haskell, the closest thing to adding 5 to an optional value would be something like:
fmap (5+) my_optional_value
This one leaves 'Nothing' alone, but adds 5 in case the value is present.Amusingly, Win API of all places generally evades this pattern: 0 timeout means "no waiting", and to wait indefinitely, you use timeout of INFINITE which is actually UINT_MAX or, equivalently, -1 (in Win API, timeouts are unsigned, not time_t).
Another example that C programmers love: using 0 to mean infinity. Eg when you have a timeout setting, and 10 means ten seconds, but 0 means infinity seconds instead of zero seconds.