我有一个C ++项目,我在我的机器上使用g++
编译(编译为“host”),并使用交叉编译器(在我的例子中为arm-cortex_a8-linux-gnueabi-g++
)编译ARM处理器。 我正在转换为C ++ 0x / 11 standart的过程中,编译初始化列表时,我得到了一个错误,我可以在以下代码片段中重现:
int main(void) { char c[1] = {-108}; }
这个程序看起来是正确的,因为-108
是char
的合法值。 用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默认情况下。