Versions Compared

Key

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

A data model defines the sizes assigned to standard data types. It is important to understand the data models used by your implementation. However, if your code depends on any assumptions not guaranteed by the standard, you should provide static assertions to ensure that your assumptions are valid. (See recommendation DCL03-C. Use a static assertion to test the value of a constant expression.) Assumptions concerning integer sizes may become invalid, for example, when porting from a 32-bit architecture to a 64-bit architecture.

...

Code frequently embeds assumptions about data models. For example, some code bases require pointer and long to have the same size, while other large code bases require int and long to be the same size [van de Voort 2007]. These types of assumptions, while common, make the code difficult to port and make the ports error prone. One solution is to avoid any implementation-defined behavior. However, this can result in inefficient code. Another solution is to include either static or runtime assertions near any platform-specific assumptions, so they can be easily detected and corrected during porting.

...

Code Block
bgColor#FFcccc
langc

FILE *fp;
int x;
/* ... */
if (fscanf(fp, "%ld", &x) < 1) {
  /* handle error */
}

...

Code Block
bgColor#ccccff
langc

FILE *fp;
int x;
/* Initialize fp */
if (fscanf(fp, "%d", &x) < 1) {
  /* handle error */
}

...

Code Block
bgColor#FFcccc
langc

unsigned int a, b;
unsigned long c;
/* Initialize a and b */
c = (unsigned long)a * b; /* not guaranteed to fit */

...

This compliant solution uses the largest unsigned integer type available if it is guaranteed to hold the result. If it is not, another solution must be found, as discussed in rule INT32-C. Ensure that operations on signed integers do not result in overflow.

Code Block
bgColor#ccccff
langc

#if UINT_MAX > UINTMAX_MAX/UINT_MAX
#error No safe type is available.
#endif
/* ... */
unsigned int a, b;
uintmax_t c;
/* Initialize a and b */
c = (uintmax_t)a * b; /* guaranteed to fit, verified above */

...

Understanding the data model used by your implementation is necessary to avoid making errors about the sizes of integer types and the range of values that they can represent. Making assumptions about the sizes of data types may lead to buffer-overflow-style attacks.

...

CERT C++ Secure Coding Standard: INT00-CPP. Understand the data model used by your implementation(s)

ISO/IEC TR 24772 "STR Bit Representationsrepresentations"

Bibliography

[Open Group 1997a]
[van de Voort 2007]

...