将未签名的值分配给已签名的char [英] Assigning an unsigned value to a signed char

查看:79
本文介绍了将未签名的值分配给已签名的char的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关C语言中类型转换的简单问题,请假定以下代码行:

Simple question on type conversion in C, assume this line of code:

signed char a = 133;

由于已签名字符的最大值为 128 ,因此上述代码是否已根据强制转换的第三条规则定义了实现?行为?

As the max value of a signed char is 128, does the above code have implementation defined behaviour according to the third rule of casting?

如果该值不能用新类型表示并且不是未签名的,则新类型是有符号的并且该值不能表示在其中;结果要么是实现定义的,要么是生成实现定义的信号.

if the value cannot be represented by the new type and it's not unsigned, then the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.

推荐答案

首先,133不是未签名的.由于它始终适合 int ,因此它的类型为 int ,并进行了签名(此外,在C99 +中,所有不带后缀的 decimal 常量都经过了签名!要获取无符号数字,必须在末尾添加 U / u .

First of all, 133 is not unsigned. Since it will always fit in an int, it will be of type int, and signed (furthermore in C99+, all unsuffixed decimal constants are signed! To get unsigned numbers you must add U/u at the end).

第二,这不是演员,而是转换.C中的强制转换是显式转换(或非转换)为某种类型,并用构造体(type)expression 标记.在这种情况下,您可以编写初始化以使用带有显式强制转换的

Second, this isn't a cast but a conversion. A cast in C is explicit conversion (or non-conversion) to a certain type, marked with construct (type)expression. In this case you could write the initialization to use an explicit cast with

signed char a = (signed char)133;

在这种情况下,它不会更改初始化的行为.

In this case it would not change the behaviour of the initialization.

第三,这确实是一个初始化,而不是赋值,因此对于可接受的表达式它具有不同的规则.如果此初始化程序用于具有静态存储持续时间的对象,则该初始化程序必须是某种编译时常量.但是对于这种特殊情况,赋值和初始化都会以相同的方式进行转换.

third, this is indeed an initialization, not an assignment, so it has different rules for what is an acceptable expression. If this initializer is for an object with static storage duration, then the initializer must be a certain kind of compile-time constant. But for this particular case, both assignment and initialization would do the conversion the same way.

现在我们要说一下第三个​​整数转换规则是否适用-为此,您需要知道前两个整数是什么:

Now we get to the point whether the 3rd integer conversion rule applies - for that you need to know what the 2 first ones are:

  1. 目标类型是一个整数类型(不是 _Bool ),其中具有可表示的值(在这种情况下不适用,因为众所周知,如果SCHAR_MAX 是127)

  1. the target type is an integer type (not _Bool) with the value representable in it (does not apply in this case since as you well know 133 is not representable if SCHAR_MAX is 127)

目标类型为 unsigned (不是)

,因此我们可以访问 C11 6.3.1.3p3 :

  1. 否则,将对新类型进行签名,并且无法在其中表示值;结果是实现定义的,还是引发实现定义的信号.

问题是它是否具有实现定义的行为-是的,实现必须记录将要发生的情况-它是如何计算结果的,或者在那种情况下会发出什么信号.

The question is whether it has implementation-defined behaviour - yes, the implementation must document what will happen - either how it calculates the result, or which signal it will raise in that occasion.

对于 GCC 10.2手册声明:

  • 当无法在该类型的对象(C90 6.2.1.2,C99和C11 6.3)中表示该值时,将整数转换为有符号整数类型的结果或发出的信号.1.3).

要转换为宽度为N的类型,该值将以2 ^ N为模减少到该类型的范围内;没有信号.

For conversion to a type of width N, the value is reduced modulo 2^N to be within range of the type; no signal is raised.

Clang的文档"是小"字样难以访问的您只需阅读源代码...

The Clang "documentation" is a "little" less accessible, you just have to read the source code...

这篇关于将未签名的值分配给已签名的char的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆