Search code examples
c++implicit-conversion

Why is compiler converting char to int in printf?


I am using https://cppinsights.io/ . Following is the code (default example)

#include <cstdio>

int main()
{
    const char arr[10]{2,4,6,8};
    for(const char& c : arr)
    {
      printf("c=%c\n", c);
    }
}

About cppinsights

C++ Insights is a clang-based tool which does a source to source transformation. Its goal is to make things visible, which normally and intentionally happen behind the scenes. It's about the magic the compiler does for us to make things work. Or looking through the classes of a compiler.

Here is the code generated, which is how compiler looks at the code

#include <cstdio>

int main()
{
  const char arr[10] = {2, 4, 6, 8, '\0', '\0', '\0', '\0', '\0', '\0'};
  {
    char const (&__range1)[10] = arr;
    const char * __begin1 = __range1;
    const char * __end1 = __range1 + 10L;
    for(; __begin1 != __end1; ++__begin1) {
      const char & c = *__begin1;
      printf("c=%c\n", static_cast<int>(c));
    }
  }
}

My question is, why is there a static_cast<int> even though %c is used.


Solution

  • In C, any argument narrower than an int is automatically promoted to an int when passed to printf, or generally when passed to any function for an argument corresponding to ... in the declaration or to any function without parameter prototypes (declared with ()). C++ Insights is explicitly showing you this promotion.

    Although the %c conversion specifier prints a character, it expects to receive that character in an int argument.

    The reason for the promotion is largely historical; C was developed in environments where computing in the native register size was easy and implementing specific semantics for other types required more work. So, in most expressions, integers narrower than int are promoted to int.