如果一个整数默认是有符号的,为什么会存在 signed 关键字?
If an integer is signed by default, why does the signed keyword exist?
我很好奇为什么存在 signed 关键字,因为我相信大多数整数和其他变量在默认情况下都是有符号的。将 signed 关键字放在 int 之前几乎没有任何作用。它有什么用,为什么存在?
至少有两个地方 signed
关键字不是空操作:
With char
: "plain" char
的符号是实现定义的。在它是无符号类型的实现中,需要 signed char
才能获得带符号的变体。即使 char
是有符号类型,signed char
、char
和 unsigned char
都是不同的类型。
使用位域:没有显式签名的位域成员具有实现定义的签名。例如,在
struct foo {
int b:1;
};
b
的取值范围可能是 { -1, 0 } 或 { 0, 1 },具体取决于实现。如果您想确保获得签名版本,则需要 signed
关键字。请注意,虽然标准对此不是很清楚,但在流行的实现中,这也适用于 typedef
:如果位域成员使用不包含显式签名的 typedef
定义的类型,则实现-定义的签名(在 GCC 上,由 -fsigned-bitfields
设置)也适用于此。这意味着像 int32_t
这样的类型应该使用 signed
关键字来定义,以避免在位域中使用时出现非常糟糕的意外行为。
char
要么是有符号的,要么是无符号的,但无论如何它是一种不同于 unsigned char
和 signed char
的类型。这三个是不同的类型:
char
signed char
unsigned char
如果不使用 signed
,则需要一些其他方法来区分它们。
即使没有char
。为什么不?它允许明确:
signed int x; // Someone decided that x
// must be signed
int y; // Did the author choose signed
// consciously? We cannot tell.
我很好奇为什么存在 signed 关键字,因为我相信大多数整数和其他变量在默认情况下都是有符号的。将 signed 关键字放在 int 之前几乎没有任何作用。它有什么用,为什么存在?
至少有两个地方 signed
关键字不是空操作:
With
char
: "plain"char
的符号是实现定义的。在它是无符号类型的实现中,需要signed char
才能获得带符号的变体。即使char
是有符号类型,signed char
、char
和unsigned char
都是不同的类型。使用位域:没有显式签名的位域成员具有实现定义的签名。例如,在
struct foo { int b:1; };
b
的取值范围可能是 { -1, 0 } 或 { 0, 1 },具体取决于实现。如果您想确保获得签名版本,则需要signed
关键字。请注意,虽然标准对此不是很清楚,但在流行的实现中,这也适用于typedef
:如果位域成员使用不包含显式签名的typedef
定义的类型,则实现-定义的签名(在 GCC 上,由-fsigned-bitfields
设置)也适用于此。这意味着像int32_t
这样的类型应该使用signed
关键字来定义,以避免在位域中使用时出现非常糟糕的意外行为。
char
要么是有符号的,要么是无符号的,但无论如何它是一种不同于 unsigned char
和 signed char
的类型。这三个是不同的类型:
char
signed char
unsigned char
如果不使用 signed
,则需要一些其他方法来区分它们。
即使没有char
。为什么不?它允许明确:
signed int x; // Someone decided that x
// must be signed
int y; // Did the author choose signed
// consciously? We cannot tell.