Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned for the pointed-to the referenced type, the behavior is undefined.

...

If the misaligned pointer is dereferenced, the program may terminate abnormally. The On some architectures, the cast alone may cause a loss of information even if the value is not dereferenced . For if the types involved have differing alignment requirements.

Noncompliant Code Example

In this noncompliant example, the

...

char pointer &c is converted to the more strictly aligned int pointer ip. 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.

Code Block
bgColor#FFCCCC
langc
#include <assert.h>
 
void func(void) {
  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.

Noncompliant Code Example

...

assert(cp == &c);
}

Compliant Solution (Intermediate Object)

In this compliant solution, the char value is stored into an int so that the pointer's value will be properly aligned:

Code Block
bgColor#FFCCCC#ccccff
langc
#include <assert.h>
 
void ffunc(void) {
  char c int *i_ptr= 'x';
  charint i = c;
 
 int i_ptr*ip = (int *)&c;  /* Violation */i;

  /* ... */
}

Compliant Solution

assert(ip == &i);
}

Compliant Solution (C11, alignas())

This compliant solution uses alignas to align the character c to the alignment of an integer. As a result, the two pointers point to equally aligned pointer typesIn this compliant solution, the value referenced by the char pointer c_ptr has the alignment of type int:

Code Block
bgColor#ccccff
langc
#include <stdalign.h>
#include <assert.h>
 
void ffunc(void) {
  char/* Align *c_ptr;
  c to the alignment of an int *i_ptr;/
  alignas(int i) char c = 'x';
 
 int c_ptr*ip = (charint *)&ic; 
  char i_ptr*cp = (intchar *)c_ptrip;
  /* ... */ Both cp and &c point to equally aligned objects */
  assert(cp == &c);
}

Noncompliant Code Example

...

Code Block
bgColor#FFCCCC
langc
char *loop_ptr;
int *int_ptr;

int *loop_function(void *v_pointer) {
  /* ... */
  return v_pointer;
}
 
void func(voidchar *loop_ptr) {
  int *int_ptr = loop_function(loop_ptr);

  /* ... */
}

This example compiles without warning. However, v_pointer can be aligned on a 1-byte boundarymore strictly aligned than an int *.

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 accept only int *:

Code Block
bgColor#ccccff
langc
int *loop_ptr;
int *int_ptr;

int *loop_function(int *v_pointer) {
  /* ... */
  return v_pointer;
}
 
void func(voidint *loop_ptr) {
  int *int_ptr = loop_function(loop_ptr);

  /* ... */
}

...

Code Block
bgColor#FFCCCC
langc
#include <string.h>
 
void func(void) {
  char *data;struct foo_header {
  int len;
  /* ... */
};
 
void func(char *data, size_t offset) {
  struct foo_header *tmp;
  struct foo_header *header;

  tmp = data + offset;
  memcpy(&header, tmp, sizeof(header));

  if (header.len < FOO) {
    /* ... */

  }
}

Unfortunately, the behavior is undefined when you assign an unaligned value to a pointer that points to a type that needs to be aligned. An implementation may notice, for example, that tmp and header must be aligned, so it could use an inlined memcpy() that uses instructions that assume aligned data.

Compliant Solution

This compliant solution does not use the foo_header pointer:

Code Block
bgColor#ccccff
langc
#include <string.h>
 
char *data;
struct foo_header header;

void func(void) {
  memcpy(&header, data + offset, sizeof(header));

  if (header.len < FOO) {
  int len;
  /* ... */

  }
}

Noncompliant Code Example

For objects declared on the stack, the C Standard provides alignas to declare an object to have a stricter alignment. It can be used to resolve the following noncompliant code example:

Code Block
bgColor#FFCCCC
langc
#include <assert.h>
;
  
void func(void) {
  char c = 'x';
  int *ip = (int *)&c; /* This can lose information */
  char *cp = (char *)ip;
  assert(cp == &c);    /* Will fail on some conforming implementations */

  /* ... */
}

Compliant Solution

This compliant solution uses alignas to align the the character c to the alignment of an integer. As a result, the two pointers point to equally aligned pointer types:

Code Block
bgColor#ccccff
langc
#include <stdalign.h>  /* For alignas() */
#include <assert.h>
 
void func(void *data, size_t offset) {
  alignas(int) char c = 'x'; /* Align c to the alignment of an int */
  int *ip = (int *)&c; 
  char *cp = (char *)ip;
  assert(cp == &c);    /* Both cp and &c point to equally aligned objects */struct foo_header header; 
  memcpy(&header, data + offset, sizeof(header));

  /* ... */
}

Risk Assessment

Accessing a pointer or an object that is no longer on the correct access boundary can not properly aligned can cause a program to crash or give wrong information, or it can cause slow pointer accesses (if the architecture allows misaligned accesses).

...

 

...