Linux   发布时间:2022-04-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了这对int64_t的处理是GCC和Clang的错误吗?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

现在,你们中的一些人会想要大喊未定义的行为,但是有一个问题. int64_t类型不是由C标准定义,而是由POSIX定义.POSIX将此类型定义为: a signed Integer type with width N, no padding bits, and a two's-complement representation. 它不会留下这个实现来定义

现在,你们中的一些人会想要大喊未定义的行为,但是有一个问题. int64_t类型不是由C标准定义,而是由@L_301_0@定义.POSIX将此类型定义为:

它不会留下这个实现来定义,并且绝对不允许将它视为无界整数.

linux$cat x.c
#include <>dio.h>
#include 

显然,这里有一个问题……它是什么?
我错过了某种隐性演员吗?

最佳答案
你不需要去POSIX对它进行排序,ISO C控制这个特定的方面(下面的参是C11标准).

这个答案的其余部分将成为所有“语言律师”,以显示为什么将未添加的行为添加到已签名的值中,以及为什么两个答案(真和假)都有效.

首先,您在ISO中未定义int64_t的争论并不十分正确.第7.20.1.1节精确宽度整数类型在引用intN_t类型时指出:

这就是为什么你不需要担心POSIX以某种方式定义这些类型的原因,因为ISO定义它们完全相同(两个补码,没有填充等),假设它具有适当的能力.

所以,既然我们已经建立了ISO确定它们(如果它们在实现中可用),现在让我们看看6.5 Expressions / 5:

添加两个相同的整数类型肯定会给你相同的类型(至少在int64_t的等级,远高于整数提升完成的点1),因为这是由6.3.1.8中规定的通常的算术转换决定的.在处理各种浮点类型(其中int64_t不是)的部分之后,我们看到:

在同一部分的早期,您会找到一个声明,该声明在找到常见类型后指示结果的类型:

因此,假设INT64_MAX 1的结果实际上不适合int64_t变量,则行为未定义.

根据你的注释,int64_t的编码表明添加一个将包装,你必须明白,它不会改变它根本未定义的子句.在这种情况下,实现仍然可以自由地执行任何操作,即使根据您的想法没有意义.

并且,在任何情况下,表达式INT64_MAX 1> INT64_MAX(其中1经历整数提升为int64_t)可以简单地编译为1,因为可以说比实际递增值和进行比较更快.这是正确的结果,因为任何东西都是正确的结果:-)

从这个意义上讲,它与实现转换没有什么不同:

int ub (int i) { return i++ * i++; } // big no-no
:
int x = ub (3);

进入更简单,几乎肯定更快:

int x = 0;

您可能认为答案会更好,因为9或12(取决于何时执行副作用)但是,如果未定义的行为是打破编码器和编译器之间的契约,编译器可以自由地做任何想做的事情.

在任何情况下,如果你想要一个定义良好的函数版本,你可以选择以下内容

int stupid (int64_t a) {
    return (a == INT64_MAX) ? 0 : 1;
}

这可以在不诉诸未定义的行为的情况下获得所需/预期的结果:-)

1如果int的宽度实际上大于64位,则此处可能存在边缘情况.在这种情况下,很可能整数提升将强制int64_t为int,允许表达式被很好地定义.我没有详细研究过,所以可能是错的(换句话说,不要把它视为我答案的福音部分)但是值得记住的是检查你是否得到了一个int的实现超过64位宽.

大佬总结

以上是大佬教程为你收集整理的这对int64_t的处理是GCC和Clang的错误吗?全部内容,希望文章能够帮你解决这对int64_t的处理是GCC和Clang的错误吗?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。