忽略符号的 C 编译器标志

Posted

技术标签:

【中文标题】忽略符号的 C 编译器标志【英文标题】:C compiler flag to ignore sign 【发布时间】:2009-09-01 13:02:23 【问题描述】:

我目前正在处理从第三方承包商处购买的代码。一个结构有一个无符号字符字段,而他们将该字段传递给的函数需要一个有符号字符。编译器不喜欢这样,因为它认为它们是不匹配的类型。然而,它显然是为那个承包商编译的。一些谷歌搜索告诉我“[i]t 是实现定义的 char 对象是否可以保存负值”。承包商的编译器可以基本上忽略有符号/无符号类型并同等对待吗?或者是否有编译器标志将它们视为相同?

C 不是我最擅长的语言——只要看看我的用户页面上的标签——所以任何帮助都将不胜感激。

【问题讨论】:

什么编译器?大多数 [如果不是全部] C 编译器将允许您更改 char 的隐式签名,但它是特定于编译器的标志,因此没有通用答案。 这家伙:docs.sun.com/source/806-3567/cc_options.html 为什么不根据需要将它们转换为正确的类型? 此代码来自尚未接听我电话的承包商。它应该可以工作,特别是因为我们得到了一个内置的包——由于其他原因无法使用。 【参考方案1】:

其实charsigned charunsigned char是三种不同的类型。来自标准(ISO/IEC 9899:1990):

6.1.2.5 类型

...

charsigned char和三种类型 unsigned char 统称为 字符类型

(例如在 C++ 中,如果你有一个 char 参数,你必须(或至少应该)用它们的三个变体编写覆盖函数)

编译器可能会处理有符号或无符号的普通字符,但标准说(也在 6.1.2.5 中):

声明为 char 类型的对象是 大到足以存储任何成员 基本执行字符集。如果 所需来源的成员 5.2.1 中的字符集存储在一个 char 对象,它的值是有保证的 要积极。如果其他数量 存储在 char 对象中, 行为是实现定义的: 这些值被视为 有符号或非负整数。

声明为 signed char 类型的对象占用与“普通”char对象相同的存储量。

5.2.1中提到的字符是A-Z、a-z、0-9、空格、制表符、换行符以及以下29个图形字符:

! " # % & ' ( ) * + , - . / :
; < = > ? [ \ ] ^ _  |  ~ 

回答

我解释的所有这些基本上意味着值小于 128 的 ascii 字符被保证为正数。因此,如果存储的值始终小于 128,则它应该是安全的(从价值保存的角度来看),尽管不是很好的做法。

【讨论】:

这段代码处理图像,所以我怀疑那里存储的不仅仅是 'A's 和 'b's。 问题已解决。显然,可能的值是 0-100,我们收到了混合版本。谢谢你的帮助。【参考方案2】:

这取决于编译器。例如,在 VC++ 中,如果该选项指示默认使用 unsigned char,则定义了一个编译器选项和一个相应的 _CHAR_UNSIGNED 宏。

【讨论】:

我认为我们使用了不同的编译器。这是一个真正的问题,因为在这里安装一个新的可能需要很长时间,如果不是不可能的话。【参考方案3】:

我认为您说的是signed charunsigned char 类型的字段,因此它们显然是错误的。如果其中一个只是char,它可能与承包商使用的任何编译器匹配(IIRC,它是实现定义的charsigned 还是unsigned),但不是你的。在这种情况下,您也许可以通过命令行选项或其他东西来更改您的选项。

或者,承包商可能正在使用编译器或编译器选项,允许他在编译时忽略错误或警告。你知道他有什么样的编译环境吗?

无论如何,这不是好的 C。如果其中一种类型只是 char,它依赖于实现定义的行为,因此不可移植。如果不是,那就大错特错了。我会向承包商提出这个问题。

【讨论】:

以上是关于忽略符号的 C 编译器标志的主要内容,如果未能解决你的问题,请参考以下文章

一个经常被忽略的c语言问题

gcc 编译器标志和符号表之间的不兼容函数地址

即使使用 -g 标志编译,gdb 中也没有调试符号

枚举类型和位标志

Visual C ++编译器选项

C编译器中是不是有调试模式编译标志的标准?