为什么编译器在 printf 中将 char 转换为 int?

Adi*_*ore 2 c++ implicit-conversion

我正在使用https://cppinsights.io/。以下是代码(默认示例)

#include <cstdio>

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

关于cppinsights

C++ Insights 是一个基于 clang 的工具,可以进行源到源的转换。它的目标是让事情可见,这通常是有意地在幕后发生。这是关于编译器为我们做的事情的魔法。或者查看编译器的类。

这是生成的代码,这是编译器如何看待代码

#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));
    }
  }
}

Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么要使用static_cast<int>即使%c

Eri*_*hil 5

在 C 中,任何比 an 更窄的参数在传递给 时int自动提升为,或者通常在传递给任何函数以用于声明中对应的参数或任何没有参数原型的函数(用 声明)。C++ Insights 明确地向您展示了此促销活动。intprintf...()

尽管%c转换说明符打印一个字符,但它希望在int参数中接收该字符。

晋升的原因主要是历史性的;C 是在本地寄存器大小的计算很容易并且为其他类型实现特定语义需要更多工作的环境中开发的。因此,在大多数表达式中,比int提升为更窄的整数int

  • 请注意,C++ 也有模板[参数包](https://en.cppreference.com/w/cpp/language/parameter_pack)。他们还使用“...”语法,但不会发生升级。相反,编译器使用正确的类型实例化模板,该类型可以是“char”。但这仅适用于本机 C++,不适用于从 C 继承的函数。 (3认同)