“交叉编译时,从”int“到”char“的转换范围缩小为合法值

我有一个C ++项目,我在我的机器上使用g++编译(编译为“host”),并使用交叉编译器(在我的例子中为arm-cortex_a8-linux-gnueabi-g++ )编译ARM处理器。 我正在转换为C ++ 0x / 11 standart的过程中,编译初始化列表时,我得到了一个错误,我可以在以下代码片段中重现:

 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 )是合法的,并不会导致两个编译器的错误。

当你将一个变量声明为char ,无论是有符号的还是无符号的,都是依赖于实现的。 如果您需要能够存储负值,则应该声明显式signed ,而不是依赖实现定义的默认值。

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

由于价值是合法的

你怎么知道? char的签名是实现定义的。 如果没有签名,你的代码就会变窄 – §8.5.4/ 7:

缩小转换是一种隐式转换
[…]
(7.4) – 从一个整数类型到一个不能表示原始类型的所有值的整数类型 ,除了源是一个常数表达式,其整数升级后的值将符合目标类型。

第8.5.1节/ 2:

如果初始化子句是一个表达式,并且需要一个缩小的转换(8.5.4)来转换表达式,则该程序是格式不正确的。

但是,如果您需要签名的char ,请使用signed char

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

…保证工作。

这应该会更好:

 signed char c[] = { (signed char)(-108) }; 

因为括号中的值可以被视为int默认情况下。