-
Notifications
You must be signed in to change notification settings - Fork 3
Conversion operations
C allow implicit conversion operations at assignments,
function call arguments, and function returns. For pointer types,
conversions between void * pointers and other pointer types are
allowed. When an expected type differs from the actual type,
and one type is void * and other type is a pointer type,
an impicit conversion is done.
The Checked C extension allows implicit conversions between different kinds of pointer types too. These must meet target bounds requirements at compile time. They cannot be points of runtime failure.
A T * can be converted to a _Ptr<T> or _Array_ptr<T>.
There are only a few kinds of T * expressions that have
known bounds, though:
int x;
_Ptr<int> p = &x; // OK, &x meets bounds requirements.
_Array_ptr<int> p = &x; // OK, no bounds required.
_Array_ptr<int> p : count(1) = &x; // OK, &x meets bounds requirements.
_Array_ptr<int> p : count(2) = &x; // Error, &x does not meet bounds requirements.
int arr[10];
_Ptr<int> r = arr; // OK, arr meets bounds requirements.
_Array_ptr<int> r = arr; // OK, no bounds required.
_Array_ptr<int> r : count(10) = r; // OK, arr meets bounds requirements.
_Array_ptr<int> r : count(11) = r; // Error, x does not meet bounds requirements.
f(int *x) {
_Ptr<int> p = x; // Error, x does not bounds requirements for Ptr.
_Array_ptr<int> r : count(1) = x; // Error, x does not bounds requirement.
}
## Conversions between checked pointer types
Some conversions between checked pointers to the same type are allowed:
- \_Ptr<T> can be converted to a \_Array_ptr<T>
- \_Array_ptr<T> can be converted to a _Ptr<T>
- \_Nt_array_ptr<T> can be converted to a _Ptr<T> or _Array_ptr<T>.
// Implicit conversion from _Ptr to _Array_ptr void f(_Array_ptr a count(len), int len); void g(_Ptr b) { f(b, 1); }
_Array_ptr c : count(5); _Ptr d = c + 2;
## Conversions to unchecked pointer types
Implicit conversions from checked pointer types to unchecked pointer types are
allowed only at
[bounds-safe interfaces](https://github.com/Microsoft/checkedc/wiki/Bounds-safe-interfaces),
where the expected checked bounds or types have been declared.
Otherwise they are not allowed.
# Explicit type conversions
There are 3 conversion operators between pointer types. In the follwoing descriptions,
the type `D` is the result type. It must be a pointer type. The expression _e_
must have a pointer or integer type. The value of each conversion operation
is the value of _e_ reinterpreted bitwise as a value of type `D`.
- C-style casts, given by `(D)` _e_. If `D` is `_Ptr<T>` or `T *`, _e_ must have space for
a value of type `T`. This must be provable at compile-time. Runtime failures
cannot occur at these casts.
- Dynamically-checked bounds casts, given by `_Dynamic_bounds_cast<T>(`_e_`,`,_bounds-expr_`)`.
The bounds of _e_ are checked at runtime against _bounds-expr_.
If the bounds are not satisfied, a runtime fault is signalled.
If `D` is a `_Ptr<T>` or `T *` type, _bounds-expr_ is omitted and
the bounds are for a single element of type `T`. Note that for count
bounds expressions, _bounds_expr_ are the bounds for the value at the new type `T`, not the original type of _e_.
- Trusted bounds cast, given by `_Assume_bounds_cast(`_e_`,`_bounds-expr_`)`.
The bounds of the resulting expression are assumed be `_bounds_expr`. If T is
a `_Ptr<S>` or `S *` type, _bounds-expr_ is omitted.
Here are examples:
// Reinterpret a pointer to an array of characters as a pointer // to an integer. _Array_ptr a : count(12) = ... _Ptr b = (_Ptr) a;
// Reinterpret pointers to characters as pointers ot integers. // lb and ub have bound(unknown), so they cannot be used // to access memory. _Array_ptr lb = (_Array_ptr) a; _Array_ptr ub = (_Array_ptr) (b + 12);
// Reinterpret a pointer to an array of characters to a pointer // to an array of integers. This will fail at runtime if // sizeof(int) > 3. _Array_ptr c : count(3) = _Dynamic_bounds_cast<_Array_ptr>(a, count(3));
// Create a checked_pointer to a hardware buffer. unsigned int hardware_buf = 0xf0000; _Array_ptr d : count(4096) = _Assume_bounds_cast<_Array_ptr>(hardware_buf, 4096);
Checked C Wiki