我有一个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]
)是合法的,并且不会导致两个编译器出错。
答案 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。