交叉编译时,“在 {} 内缩小从 'int' 到 'char' 的转换”以获得合法值

新手上路,请多包涵

我有一个 C++ 项目,我在我的机器上使用 g++ 编译(编译到“主机”)和使用交叉编译器编译到 ARM 处理器(在我的例子中是 arm-cortex_a8-linux-gnueabi-g++ )。我正在转换为 C++0x/11 标准,编译初始化列表时出现错误,我能够在以下代码段中重现该错误:

 int main(void) {
    char c[1] = {-108};
}

这个程序似乎是正确的,因为 -108char 的合法值。用 g++ 编译它不会产生以下命令行错误:

 g++ example.cc -std=c++0x

但是,当我使用交叉编译器进行编译时,如下所示:

 arm-cortex_a8-linux-gnueabi-g++ example.cc -std=c++0x

我收到以下错误:

 example.cc: In function 'int main()':
example.cc:2:22: error: narrowing conversion of '-0x0000000000000006c' from 'int' to 'char' inside { } [-fpermissive]

由于该值是合法的,这似乎是一个错误。你能解释一下为什么我会收到这个错误以及如何解决它吗?

编辑:请注意,使用正值(例如 108 )是合法的,不会导致两个编译器出错。

原文由 Andy Thomas 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 788
2 个回答

当您将变量声明为 char 时,它是有符号还是无符号取决于实现。如果您需要能够存储负值,您应该明确声明它 signed ,而不是依赖于实现定义的默认值。

 signed char c[1] = { -108 };

原文由 Barmar 发布,翻译遵循 CC BY-SA 3.0 许可协议

所有 8 位值都可以由 char 对象(在典型的现代硬件上)清楚地表示,因此分配这样的值应该是安全的(*)。

如果文字是 char 类型,编译器不会发出警告。 转义序列 允许您提供十六进制数字作为字符文字:

 int main(void) {
    char c[1] = {'\x94'};
}

这将在具有签名或未签名 char 的系统上编译而不会触发 -Wnarrowing示例)。

(*) 这里的安全意味着不会丢失任何信息,尽管该值可能不是您所期望的:-108 如果 char 已签名,而 148 是 char 未签名。

原文由 John McFarlane 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题