如果我以可移植性为目标,我应该对具有负值的字符使用带符号的字符吗?

Posted

技术标签:

【中文标题】如果我以可移植性为目标,我应该对具有负值的字符使用带符号的字符吗?【英文标题】:Should I use signed char for characters with negative values if I target portability? 【发布时间】:2021-02-17 21:05:53 【问题描述】:

char 数据类型不能保证被签名,这意味着在某些实现上它是signed,而在其他实现上它是unsigned。那么为什么人们总是忽略signed 限定符呢?

char c = 'C'; // can be signed or unsigned
signed char sc = 'D'; // explicitly signed
unsigned char uc = 'e'; // explicitly unsigned

为了可移植性,如果我希望字符保持负值,我是否应该始终使用 signed 限定 char

据我所知,intlongshort 等其他类型始终为 signed,除非使用 unsigned 明确限定。

【问题讨论】:

char 的签名应该无关紧要,除非您滥用该类型。 如果您需要一个 1 字节的整数,请使用 int8_tuint8_t。不要使用纯字符进行计算。 你能给我们一个实际的例子,而不是仅仅说“如果我想让角色保持负值”吗?你为什么要那样做? 【参考方案1】:

char 类型主要用于存储字符(或者,在 Unicode 时代,部分字符代码)。从这个意义上说,你不应该关心它是否有符号,只要它能够表示字符。

当您需要char 大小的整数时,您应该使用signed charunsigned char 或其典型别名之一(例如int8_tuint8_t)。这将确保签名并区分类型和字符。

【讨论】:

还是时下流行的字符转换功能like std::tolower @Maestro 从 C++20 开始,这将导致值被截断(请参阅我之前评论中的链接)。在 C++20 之前,结果是实现定义的。 "当你需要char 大小的整数时,你应该使用signed charunsigned char" - 嗯,不,你不应该使用char当你需要整数时。 “或其典型别名之一(例如int8_tuint8_t” - 是的,改为这样做。 @Maestro:在进行数学计算时使用intunsigned int。这些类型通常是处理器寄存器的大小(编译器通常会为此进行优化)。唯一需要使用 int8_tuint8_t 的情况是当您需要或限制为 8 位数量时(例如在嵌入式系统中,可能还有密码学)。 不使用 8 位值进行数学运算的一个问题是处理器针对更大的字长(如 32 位或 64 位)进行了优化,并且 8 位值非常严格,只有 256组合或范围。

以上是关于如果我以可移植性为目标,我应该对具有负值的字符使用带符号的字符吗?的主要内容,如果未能解决你的问题,请参考以下文章

当我以 32 宽的 warp CUDA 架构为目标时,我应该使用 warpSize 吗?

如何在 C 中以可移植的方式管理内存对齐和通用指针算法?

以可移植的方式使用 DB Api

如何以可移植的方式在 C 中执行算术右移?

以可移植数据格式保存/加载 scipy sparse csr_matrix

为啥我应该在 Xamarin 中使用可移植类库?