Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
747 views
in Technique[技术] by (71.8m points)

c - Why do unsigned "small" integers promote to signed int?

The standard is clear: when performing arithmetic on an integral type smaller than int, the integer is first promoted to a signed int, unless int cannot represent the full range of values for the original type, in which case the promotion is to unsigned int instead.

My question is: what is (was?) the motivation for this policy? Why are unsigned types promoted to signed int, rather than always to unsigned int?

Of course, in practice there's almost no difference, since the underlying assembly instruction is the same (just a zero-extension), but there is a key downside to promotion to signed int, without obvious upside, since overflows are UB in signed arithmetic but well-defined in unsigned arithmetic.

Were there historical reasons for preferring signed int? Are there architectures that don't use two's complement arithmetic where promotion of small unsigned types to signed int rather than unsigned int is easier/faster?

EDIT: I would think it's obvious, but here I'm looking for facts (i.e. some documentation or references that explain the design decision), not "primarily opinion-based" speculation.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is addressed in the ANSI C Rationale (the link is to the relevant section, 3.2.1.1). It was, to some extent, an arbitrary choice that could have gone either way, but there are reasons for the choice that was made.

Since the publication of K&R, a serious divergence has occurred among implementations of C in the evolution of integral promotion rules. Implementations fall into two major camps, which may be characterized as unsigned preserving and value preserving. The difference between these approaches centers on the treatment of unsigned char and unsigned short, when widened by the integral promotions, but the decision has an impact on the typing of constants as well (see §3.1.3.2).

The unsigned preserving approach calls for promoting the two smaller unsigned types to unsigned int. This is a simple rule, and yields a type which is independent of execution environment.

The value preserving approach calls for promoting those types to signed int, if that type can properly represent all the values of the original type, and otherwise for promoting those types to unsigned int. Thus, if the execution environment represents short as something smaller than int, unsigned short becomes int; otherwise it becomes unsigned int.

[SNIP]

The unsigned preserving rules greatly increase the number of situations where unsigned int confronts signed int to yield a questionably signed result, whereas the value preserving rules minimize such confrontations. Thus, the value preserving rules were considered to be safer for the novice, or unwary, programmer. After much discussion, the Committee decided in favor of value preserving rules, despite the fact that the UNIX C compilers had evolved in the direction of unsigned preserving.

(I recommend reading the full section. I just didn't want to quote the whole thing here.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...