c - 这种对 int64_t 的处理是 GCC 和 Clang 错误吗?

标签 c linux gcc clang posix

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

a signed integer type with width N, no padding bits, and a two's-complement representation.

它不会将此留给实现来定义,而且绝对不允许将其视为无界整数。

linux$ cat x.c
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

int stupid (int64_t a) {
  return (a+1) > a;
}

int main(void)
{
    int v;
    printf("%d\n", v = stupid(INT64_MAX));
    exit(v);
}

linux$ gcc -ox x.c -Wall && ./x
0
linux$ gcc -ox x.c -Wall -O2 && ./x # THIS IS THE ERROR.
1
linux$ gcc --version
gcc (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

linux$ uname -a
Linux localhost 3.14.13-0-amd64 #1 SMP Sat Jul 26 20:03:23 BST 2014 x86_64 GNU/Linux
linux$ getconf LONG_BIT
32
linux$

显然,这里有一个问题......它是什么?
我是否错过了某种隐式转换?

最佳答案

我还是要喊未定义的行为

这里的推理很简单,编译器假定您是一个完美的程序员并且永远不会编写任何可能导致未定义行为的代码。

所以当它看到你的函数时:

int stupid (int64_t a) {
  return (a+1) > a;
}

它假定您永远不会用 a==INT64_MAX 调用它,因为那将是 UB。

因此,这个函数可以简单地优化为:

int stupid (int64_t a) {
  return 1;
}

然后可以根据需要内联。

我建议你阅读 What Every C Programmer Should Know About Undefined Behavior有关编译器如何利用 UB 进行优化的更多解释。

关于c - 这种对 int64_t 的处理是 GCC 和 Clang 错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29578540/

相关文章:

c - 为什么不是 scanf ("%*[^\n]\n");和 scanf ("%*[^\n]%*c");清除挂起的换行符?

linux - 有什么方法可以在linux中保留但不提交内存?

c++ - 链表结构推送和弹出

c - 为什么它会改变变量的值?

linux - 从命令行保存某个字符串

c++ - 带有命令行参数的 C++ Makefile 和 Bash 脚本

c - 为什么使用 malloc 分配内存块不遵循首次适应?

c - 错误: 'for' loop initial declarations are only allowed in c99 mode

gcc - 用gcc/mingw编译intel程序集

我可以指向代码,然后传递给下一条指令吗?