C++ 如何检查纯字符是有符号的还是无符号的?

C++ 如何检查纯字符是有符号的还是无符号的?,c++,syntax,char,C++,Syntax,Char,显然,默认情况下,纯char可以是有符号的,也可以是无符号的。Stroustrup写入: 普通字符是有符号还是无符号是由实现定义的。这将打开 可能会出现一些令人不快的意外情况和实现依赖性 如何检查我的字符是否已签名?我可能想稍后将它们转换为int,但我不希望它们是负数。我应该总是显式地使用无符号字符吗 来自标题 std::numeric\u limits::is\u signed 一些备选方案: const bool char_is_signed = (char)-1 < 0; #inc

显然,默认情况下,纯
char
可以是有符号的,也可以是无符号的。Stroustrup写入:

普通字符是有符号还是无符号是由实现定义的。这将打开 可能会出现一些令人不快的意外情况和实现依赖性

如何检查我的字符是否已签名?我可能想稍后将它们转换为
int
,但我不希望它们是负数。我应该总是显式地使用
无符号字符吗

来自标题

std::numeric\u limits::is\u signed

一些备选方案:

const bool char_is_signed = (char)-1 < 0;

#include <climits>
const bool char_is_signed = CHAR_MIN < 0;
constboolchar\u有符号=(char)-1<0;
#包括
const bool char\u有符号=char\u MIN<0;
是的,有些系统确实将纯
char
作为无符号类型。我遇到的例子有:Cray T90、Cray SV1、Cray T3E、SGI MIPS IRIX、IBM PowerPC AIX。任何使用EBCDIC的系统几乎都必须使纯
char
无符号,以便所有基本字符都具有非负值。(有些编译器可以选择控制
字符的签名,例如gcc的
-fsigned char
-funsigned char

但是,
std::numeric\u limits::is\u signed
,正如所建议的,可能更清楚地表达了意图


(另一方面,我建议的方法也可以应用于C。)

您可以使用预处理器命令:

 #define is_type_signed(my_type) (((my_type)-1) < 0)
#定义是有符号的(我的类型)((我的类型)-1<0)

使用
无符号字符
“始终”可能会给您带来一些有趣的惊喜,因为大多数C风格函数,如
printf
fopen
,将使用
字符
,而不是
无符号字符

编辑:C风格函数的“乐趣”示例:

const unsigned char *cmd = "grep -r blah *.txt";
FILE *pf = popen(cmd, "r"); 
将给出错误(事实上,我为
*cmd=
行得到一个错误,为
popen
行得到一个错误)。使用
constchar*cmd=…
可以很好地工作。我选择了<代码> POPON < /C>因为它是一个不需要用一些标准的C++功能替换的函数——很明显,<代码> Prtff < /C>或<代码> fOpen< /Cord>可以很容易地被一些<代码> IoSturi或<代码> FSturt类型功能所取代,它通常有两种选择,一种是
无符号字符
,另一种是
字符


但是,如果您使用的是
是,如果您希望使用
字符
类型,并且您始终希望它是无符号的,请使用
无符号字符
。请注意,与其他基本整数类型不同,
unsigned char
是与
char
不同的类型,即使在
char
为无符号的系统上也是如此。另外,从
char
转换为
int
,因此如果结果不正确,则源
char
值也可能不正确

测试代码<> char < /c>是否为最新方法,取决于是否需要它是预处理器测试,以及C++的目标版本。 要使用预处理器测试有条件地编译代码,的值应起作用:

#include <climits>

#if (CHAR_MIN==0)
// code that relies on char being unsigned
#endif
如果您是针对C++11或C++14编写的,则需要稍微详细一点,并且:

#包括
静态断言(std::is_unsigned::value,“char is signed”);
//依赖于未签名字符的代码

<> P>对于C++的所有修订,@ benjamin lindley的解决方案是一个很好的选择。

为什么要把它变成宏,而不是说“代码> const BOOL ?”@ KeththoppSon,这是更“普遍”的结构,而不是仅仅用于字符类型。“你在试图传达信息。@MitchWheat:是的。我遇到的例子有:Cray T90、Cray SV1、Cray T3E、SGI MIPS IRIX、IBM PowerPC AIX。任何使用EBCDIC的系统几乎都必须使纯
char
无符号。@KeithThompson:您应该添加列表作为阅读编译器文档的答案。@PeteBecker:如果您想在编译时或运行时检查,这不一定有帮助(尽管通常编写的代码最好不关心
char
是有符号的还是无符号的,或者使用
signed char
unsigned char
,如果你关心的话)。@KeithThompson-是的,很明显,这就是为什么我发表了一条评论而不是答案。@chux:还没有完成编辑。。。(自我提示:先写编辑,然后评论说“见编辑”)
#include <type_traits>

static_assert(std::is_unsigned_v<char>);
// code that relies on char being unsigned
#include <type_traits>

static_assert(std::is_unsigned<char>::value, "char is signed");
// code that relies on char being unsigned