C 积分提升/转换:为什么我要关心结果类型的名称?

C 积分提升/转换:为什么我要关心结果类型的名称?,c,type-conversion,standards,c99,integer-promotion,C,Type Conversion,Standards,C99,Integer Promotion,我一直试图了解C99积分提升规则和积分类型的常用算术转换。在燃烧了一些神经元后,我提出了一套我自己的规则,这套规则简单得多,但我相信,相当于官方的规则: 更新:为了回答这个问题,我首先定义“物理类型”,如下所示 定义:如果两个整数类型具有相同的大小和符号,则它们是相同的物理类型 如果你认为这个定义有问题,那么你可能对问题2有一个很好的答案 简化的升级/转换规则 类型排名:在两种积分类型T1和T2中,“最佳”是: 以较大者为准 如果大小相同,以无符号为准 如果它们有相同的大小和符号,它们中的任何

我一直试图了解C99积分提升规则和积分类型的常用算术转换。在燃烧了一些神经元后,我提出了一套我自己的规则,这套规则简单得多,但我相信,相当于官方的规则:

更新:为了回答这个问题,我首先定义“物理类型”,如下所示

定义:如果两个整数类型具有相同的大小和符号,则它们是相同的物理类型

如果你认为这个定义有问题,那么你可能对问题2有一个很好的答案

简化的升级/转换规则

类型排名:在两种积分类型T1和T2中,“最佳”是:

  • 以较大者为准
  • 如果大小相同,以无符号为准
  • 如果它们有相同的大小和符号,它们中的任何一个,因为它们在物理上是一样的
整体提升:T型值应提升为

提升(T)=最佳(T,int)

积分类型的常用算术转换:在对T1和T2类型的二进制运算符求值之前,应将参数转换为合适的通用类型,即:

普通(T1,T2)=最佳(T1,T2,int)

注意事项:虽然我相信我的规则给出了正确的物理类型,但在单个类型具有不同名称的情况下,它们可能无法提供正确的类型名称。例如,在
int==long
的系统上,官方规则说

公共(无符号整数,长)=无符号长

而我的规则是
unsigned int
(这在物理上是相同的)。但这不应该是个问题,因为名字并不重要。还是他们

在这漫长的序曲之后,真正的问题来了,它有两个方面:

问题1:我的规则正确吗? 我读了好几遍官方文件,但仍然觉得它们令人困惑。因此,我可能误解了一些东西。如果我错了,请提供一个官方规则和我的规则产生不同类型的例子。我的意思是:不同的物理类型,而不仅仅是物理上相同的不同类型

最好是一个真实世界的例子。如果找不到,那么如果假设的C环境描述得足够详细(相关类型的大小等),理论上的例子就可以了

如果我在这里是正确的,那么第二个问题就变得相关了

问题2:我为什么要关心升级/转换类型的名称? 如果我是对的,那么一个显而易见的问题就是“为什么标准委员会的人要写这么复杂的规则?”。我能想到的唯一答案是,他们不仅要指定升级/转换产生的物理类型,还要指定命名这些类型的正确方法。但是,为什么他们会在意呢?这些类型只在编译器内部使用,只要我们理解它们的物理性质,命名它们并不重要。这个推理有什么问题吗?你能想象这样一种情况吗?T1和T2在物理上是相同的,但重要的是要知道事物是否自动升级或转换为T1而不是T2?同样,最好是一个真实世界的例子,否则,如果足够详细,理论例子也可以

根本原因 (2014年11月10日增加了一节,以解决一些意见)

在搜索这些主题时,我总是看到在算术运算符行为的上下文中讨论这些主题,更具体地说是在这些运算符返回的结果中讨论这些主题。例如,表达式
-1L<1U
是有问题的,因为在long确实比int长的系统上是正确的,但在其他系统上则是错误的。我认为理解这类问题是一件好事,但需要一个复杂的规则集来理解是一件坏事。因此,我们努力构建一个更简单的规则集,可靠地给出相同的结果

我完全明白我的规则对那些认为真正的规则足够简单的人来说是无用的。我也理解,并尊重地不同意那些认为依赖官方规则以外的任何东西本质上都是有害的观点。不过,如果我的规则只对我有帮助的话,它还是有用的

关于我的个人偏见:作为一名物理学家,我非常看重简单。我习惯于处理那些不是——也不是注定要成为——终极真理的理论,但它们被证明是非常有用的,并且只要你理解它们的适用范围,就可以安全地使用。在任何给定的情况下,最好的理论都不是最完整的:它是最简单的,仍然适用。例如:我不会用量子引力来计算单摆的周期。我在这里发布这个问题是为了就上述规则的适用范围征求专家意见

到目前为止,我得到的是:

  • varargs案件(坦克,mafso),这似乎是C99中这些规则至少在原则上不适用的唯一情况
  • \u Generic
    关键字(谢谢,Pascal Cuoq),作为C11的一个特性,稍微超出了范围
  • C++11
    auto
    关键字,它超出了范围,但有趣的是,它会将关于别名规则的问题(否则不相关)带到表中

关于你的第一个问题,我认为答案是“是”:在所有正常的或甚至稍微有异国情调的平台上,你提出的规则产生了与标准规则相同的表示形式

关于你的第二个问题,这里有两种情况
{
  long *p;
  int x;
  …
  x = 1; /* 1 */
  *p = 2;
  return x; /* 3 */
}