Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: changes to examples to match new coding guidelines

...

The only integer type conversions that are guaranteed to be safe for all data values and all possible conforming implementations are conversions of an integral value to a wider type of the same signedness. Section Subclause 6.3.1.3 of the C Standard [ISO/IEC 9899:2011] says,

...

Code Block
bgColor#FFcccc
langc
#include <limits.h>
 
void func(void) {
  unsigned long int u_a = ULONG_MAX;
  signed char sc;
  sc = (signed char)u_a; /* cast eliminates warning */
  /* ... */
}

Compliant Solution (Unsigned to Signed)

...

Code Block
bgColor#ccccff
langc
#include <limits.h>
 
void func(void) {
  unsigned long int u_a = ULONG_MAX;
  signed char sc;
  if (u_a <= SCHAR_MAX) {
    sc = (signed char)u_a;  /* use cast to eliminate warning */
  }
 else {
    /* handle error condition */
  }
}

Noncompliant Code Example (Signed to Unsigned)

...

Code Block
bgColor#FFcccc
langc
#include <limits.h>

void func(void) {
  signed int si = INT_MIN;
  unsigned int ui = (unsigned int)si;  /* cast eliminates warning */

  /* ... */
}

Compliant Solution (Signed to Unsigned)

...

Code Block
bgColor#ccccff
langc
#include <limits.h>

void func(void) {
  signed int si = INT_MIN;
  unsigned int ui;
  if (si < 0) {
    /* handle error condition */
  }
 else {
    ui = (unsigned int)si;  /* cast eliminates warning */
  }
  /* ... */
}

NOTE: Although unsigned types can usually represent all positive values of the corresponding signed type, this relationship is not guaranteed by the C Standard.

...

A loss of data (truncation) can occur when converting from a signed type to a signed type with less precision. The following code can result in truncation:

Code Block
bgColorFFcccc#FFcccc
langc
#include <limits.h>

void func(void) {
  signed long int s_a = LONG_MAX;
  signed char sc = (signed char)s_a; /* cast eliminates warning */
  /* ... */
}

Compliant Solution (Signed, Loss of Precision)

...

Code Block
bgColor#ccccff
langc
#include <limits.h>

void func(void) {
  signed long int s_a = LONG_MAX;
  signed char sc;
  if ( (s_a < SCHAR_MIN) || (s_a > SCHAR_MAX) ) {
    /* handle error condition */
  }
 else {
    sc = (signed char)s_a; /* use cast to eliminate warning */
  }
  /* ... */
}

Conversions from signed types with greater precision to signed types with lesser precision require both the upper and lower bounds to be checked.

...

A loss of data (truncation) can occur when converting from an unsigned type to an unsigned type with less precision. The following code results in a truncation error on most implementations:

Code Block
bgColorFFcccc#FFcccc
langc
#include <limits.h>

void func(void) {
  unsigned long int u_a = ULONG_MAX;
  unsigned char uc = (unsigned char)u_a;  /* cast eliminates warning */
  /* ... */
}

Compliant Solution (Unsigned, Loss of Precision)

...

Code Block
bgColor#ccccff
langc
#include <limits.h>

void func(void) {
  unsigned long int u_a = ULONG_MAX;
  unsigned char uc;
  if (u_a > UCHAR_MAX) ) {
    /* handle error condition */
  }
 else {
    uc = (unsigned char)u_a; /* use cast to eliminate warning */
  }
  /* ... */
}

Conversions from unsigned types with greater precision to unsigned types with lesser precision require only the upper bounds to be checked.

...

[Dowd 2006]Chapter 6, "C Language Issues" ("Type Conversions," pp. 223–270)
[ISO/IEC 9899:2011]Section Subclause 6.3.1.3, "Signed and Unsigned Integers"
[Seacord 2013]Chapter 5, "Integer Security"
[Viega 2005]Section 5.2.9, "Truncation Error"
Section 5.2.10, "Sign Extension Error"
Section 5.2.11, "Signed to Unsigned Conversion Error"
Section 5.2.12, "Unsigned to Signed Conversion Error"
[Warren 2002]Chapter 2, "Basics"
[xorl 2009]"CVE-2009-1376: Pidgin MSN SLP Integer Truncation"

...