"缩小来自' int'去#char;'在{}"交叉编译时的合法值

时间:2015-07-26 08:16:17

标签: c++ linux c++11 cross-compiling

我有一个C ++项目,我在我的机器上使用g++编译(编译到"主机")和使用交叉编译器的ARM处理器(在我的情况下{{1} })。我正在转换为C ++ 0x / 11标准版,并且在编译初始化列表时出现错误,我可以在以下代码段中重现:

arm-cortex_a8-linux-gnueabi-g++

此计划看似正确,因为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] )是合法的,并且不会导致两个编译器出错。

3 个答案:

答案 0 :(得分:19)

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

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

答案 1 :(得分:9)

  

由于价值合法

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

  

缩小转化是隐式转换[...]
(7.4) -   从整数类型[...]到整数类型   除了之外,它不能代表原始类型的所有值   其中source是一个常量表达式,其积分促销后的值将适合目标类型。

第8.5.1节/ 2:

  

如果 initializer-clause 是一个表达式,并且转换表达式需要缩小转换(8.5.4),程序就会格式不正确。

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

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

...保证可以正常工作。

答案 2 :(得分:-1)

这应该更好:

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

因为在括号中,默认情况下可以将值视为int。