我目前正在处理从第三方承包商处购买的代码。一个结构有一个unsigned char字段,而它们传递该字段的函数需要一个signed char。编译器不喜欢这样,因为它认为它们是不匹配的类型。但是,它显然是为那个承包商编制的。一些谷歌搜索告诉我,“[i]是实现定义的char对象是否可以保留负值”。承包商的编译器基本上可以忽略有符号/无符号类型并对它们进行相同处理吗?或者是否有一个编译器标志会对它们进行同样的处理?
C不是我最强的语言 - 只需查看我的用户页面上的标签 - 所以任何帮助都会非常感激。
答案 0 :(得分:3)
实际上char
,signed char
和unsigned char
是三种不同的类型。从标准(ISO / IEC 9899:1990):
6.1.2.5类型
...
三种类型 char ,签名字符和 统称为 unsigned char 字符类型。
(例如,在C ++中,如果你有一个char参数,你必须(或者至少应该)用它们的三个变体来编写覆盖函数)
编译器可能会对普通字符进行有符号或无符号处理,但标准说明(也在6.1.2.5中):
声明为 char 类型的对象是 大到足以存储任何成员 基本执行字符集。如果 所需来源的成员 5.2.1中的字符集存储在一个 char 对象,其值是保证的 要积极。如果是其他数量 存储在 char 对象中 行为是实现定义的: 这些值被视为 有符号或非负整数。
和
声明为signed signed char类型的对象占用与“plain” char 对象相同的存储量。
5.2.1中提到的字符是A-Z,a-z,0-9,空格,制表符,换行符和以下29个图形字符:
! " # % & ' ( ) * + , - . / :
; < = > ? [ \ ] ^ _ { | } ~
我所解释的所有内容基本上都意味着值小于128的ascii字符保证是正面的。因此,如果存储的值总是小于128,那么它应该是安全的(从保留值的角度来看),尽管不是那么好的做法。
答案 1 :(得分:1)
这是依赖于编译器的。例如,在VC ++中,如果该选项指示默认使用unsigned char,则会定义编译器选项和相应的_CHAR_UNSIGNED宏。
答案 2 :(得分:0)
我认为你在谈论signed char
和unsigned char
类型的字段,所以它们明显是错误的。如果其中一个只是char
,它可能与承包商正在使用的任何编译器匹配(IIRC,它的实现定义char
是signed
还是unsigned
),但是不在你的。在这种情况下,您可以使用命令行选项或其他内容来更改您的选项。
或者,承包商可能正在使用编译器或编译器选项,允许他在忽略错误或警告的同时进行编译。你知道他有什么样的编译环境吗?
在任何情况下,这都不好C.如果其中一个类型只是char
,它依赖于实现定义的行为,因此不可移植。如果没有,那就错了。我会和承包商讨论这件事。