Different alignments are possible for different types of objects. If the type-checking system is overridden by an explicit cast or the pointer is converted to a void pointer (void *
) and then to a different type, the alignment of an object may be changed.
If the misaligned pointer is dereferenced, the program may terminate abnormally. The cast alone may cause a loss of information, even if the value is not dereferenced. For example, the following code is not guaranteed to work conforming C99 implementations, even though no pointers are dereferenced:
Code Block |
---|
char c = 'x';
int *ip = (int *)&c; /* this can lose information */
char *cp = (char *)ip;
assert(cp == &c); /* will fail on some conforming implementations */
|
On some implementations cp
will not match &c
.
As a result, if a pointer to one object type is converted to a pointer to a different object type, the second object type must not require stricter alignment than the first.
...
This example compiles without warning. However, v_pointer
may be aligned on a one-byte boundary. Once it is cast to an int *
, some architectures require that the object is aligned on a four-byte boundary. If int_ptr
is later dereferenced, the program may terminate abnormally. Simply casting to int *
may cause a loss of information, even if the value is not dereferenced. For example, the following code is not guaranteed to work conforming C99 implementations, even though no pointers are dereferenced:
Code Block | ||
---|---|---|
| ||
char c = 'x';
int *p = (int*) &c; /* this can lose information */
char *p2 = (char*) p;
assert(p2 == &c); /* will fail on some conforming implementations */
|
On some implementations p2 will not match &c.
One solution is to ensure that loop_ptr
points to an object returned by malloc()
because this object is guaranteed to be aligned properly for any need. However, this is a subtlety that is easily missed when the program is modified in the future. It is cleaner to let the type system document the alignment needs.
Compliant Solution
Because the input parameter directly influences the return value, and loop_function()
returns an int *
, the formal parameter v_pointer
is redeclared to only accept int *
.
Code Block | ||
---|---|---|
| ||
int *loop_ptr; int *int_ptr; int *loop_function(int *v_pointer) { /* ... */ return v_pointer; } int_ptr = loop_function(loop_ptr); |
Another solution is to ensure that loop_ptr
points to an object returned by malloc()
because this object is guaranteed to be aligned properly for any need. However, this is a subtlety that is easily missed when the program is modified in the future. It is easier and safer to let the type system document the alignment needs.
Risk Assessment
Accessing a pointer or an object that is no longer on the correct access boundary can cause a program to crash or give wrong information, or may cause slow pointer accesses (if the architecture allows misaligned accesses).
...