79291785

Date: 2024-12-18 16:27:41
Score: 0.5
Natty:
Report link

The other 2 answers are both correct, but due to my career history I have some additional information to share.

With the advent of the C99 standard came <stdint.h> which was a great gift for those developing C code which needed to be portable across different platforms. However, the printf family format specifiers had already been in place before C99 and retained their meaning, and are dependent upon the size of an int for each platform. If a development team used <stdint.h> types to pass with printf-family format specifiers, this causes the code to no longer be portable across different platforms. Let us take your code example above for illustration:

#include <stdio.h>
#include <inttypes.h>

void main(void)
{
    int32_t a = 44;

    fprintf(stdout, "%d\n", a);         // Only safe on 32-bit platform.
    fprintf(stdout, "%"PRId32"\n", a);  // Safe on all platforms.
}

Let us also consider the microcontroller world, in which the same C code might need to be shared among different platforms (a.k.a. the size of the CPU's registers, which typically matches the size of the stack word -- which is where the printf family of functions comes in). The printf family of functions uses the chain of format specifiers to know where to read from the stack, and one of the format specifiers ("%n") accepts a pointer input, allowing the printf functions to WRITE a value out to an integer variable, so it is imperative that the chain of format specifiers and the actual stack contents be in precise agreement, or else it can risk the printf function reading from incorrect locations on the stack, or worse with the "%n" specifier, if a pointer is being read from the stack to which it will write, and it reads from an incorrect location on the stack, the probability that it will write to a dangerous (unintended) place in RAM is very high.

Consider these platforms:

Let us consider the first call to fprintf() above: that will only be correct (and safe) on a 32-bit platform. If the code is used with an 8- or 16-bit platform, the format specifier will need to be changed to "%ld" to be correct (and thus safe). In other words, the code is not portable.

To solve this, C99 came with <inttypes.h> which has printf specifier-translation macros for the various int types that came with <stdint.h> so that printf family format specifier strings can be portable.

How do you make it portable? Use specifiers as used in the 2nd call to fprintf() above. (Since PRId32 equates to a string constant [with quotation marks], the C compiler concatenates the strings together at compile time, thus, passing only one string constant to the fprintf() function.

Reasons:
  • Blacklisted phrase (1): How do you
  • Long answer (-1):
  • Has code block (-0.5):
  • Contains question mark (0.5):
  • Low reputation (0.5):
Posted by: V. Wheeler