探究C语言标准库limits.h关于INT_MIN宏的奇怪定义

简介:

最近在读《深入理解计算机系统》(顺便打个广告,卡内基梅隆出品的这本书绝对精品),在书的48页提到了在C语言标准库limits.h中将int类型的最小值INT_MIN定义为-INT_MAX-1。书中提到了为何不写做-2147483648或者0x80000000,但是并没有给出解释,只是说这需要我们钻研C语言标准的一些比较隐晦的角落。

我们先看看MSVC的相关头文件内容:

GCC也给出了类似的定义方式:

为何是这样呢?这个头文件对我来说并不陌生。这几个宏也时常在用着,但是从没有注意过这个细节问题。百度一番后没找到满意的答案,最后勉强找到了http://www.hardtoc.com/archives/119这个比较靠谱的答案。因为英文看起来比较麻烦,再者作者描述的也不是很清楚,我写篇文章 权当翻译 一下,再加上一点点自己查到的内容。

我们先来查看C语言标准文档是怎么解释常量的,ISO/ANSI C99 和C11对于这里的描述是相同的。我们摘录下来:

“An integer constant begins with a digit, but has no period or exponent part. It may have a prefix that specifies its base and a suffix that specifies its type.”

大概意思是“一个常量起始于一个数字,但是不包含小数点或指数的部分。并且可能有一个用于指定数字基底的前缀和一个指定类型的后缀。”

这里的前缀比如16进制的0x,后缀比如指明是长整型的L或者无符号的U。

简而言之,c99对整数的定义是这样的:


D                        [0-9]
IS                       (u|U|l|L)*
{D}+{IS}?
 

不知道大家有没有注意到,这里没有提到正负号,或而言之,常量不包含符号。

下一段引用自 幻の上帝:

C语言中的常量(constant)和常量表达式(constant expression)是两个概念。前者是语法规定的一些记号(token);后者语法本质是条件表达式(conditional-expression),只是加了能在翻译而不是运行时求值的语义限制。 C语言中的常量(constant)和常量表达式(constant expression)是两个概念。前者是语法规定的一些记号(token);后者语法本质是条件表达式(conditional-expression),只是加了能在翻译而不是运行时求值的语义限制。

那么,我们假设INT_MIN定义为-2147483648,这里的-2147483648其实是由一个一元运算符-和一个常量2147483648组成,编译器怎么解释2147483648呢?编译器对于这么一个数字,按照定义好的变量顺序一一匹配其类型,这个定义好的顺序在文档里可以查到,C99和C11是一样的,另外C++11也是相同的。截图如下:

首先是由int开始,因为2147483648超过了int的最大取值范围2147483647,所以会被认为是long int类型。按照C语言的表达式求值规则,原本可能使用的x < INT_MIN这样的表达式,x被转换为long int类型再进行表达式求值了,便有可能会出现一些预料之外的结果,而按照-2147483647-1这样的定义,不会被认为是long int类型的,这个小技巧使得我们获得了正确的类型和正确的值。

这样解释不知道大家明白了没有?

这篇文章基本上是查证和翻译了,如果说有版权的话,原始版权归原作者所有。


目录
相关文章
|
2天前
|
存储 算法 C语言
数据结构基础详解(C语言):单链表_定义_初始化_插入_删除_查找_建立操作_纯c语言代码注释讲解
本文详细介绍了单链表的理论知识,涵盖单链表的定义、优点与缺点,并通过示例代码讲解了单链表的初始化、插入、删除、查找等核心操作。文中还具体分析了按位序插入、指定节点前后插入、按位序删除及按值查找等算法实现,并提供了尾插法和头插法建立单链表的方法,帮助读者深入理解单链表的基本原理与应用技巧。
|
29天前
|
搜索推荐 算法 Java
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
该博客文章通过UML类图和Java源码示例,展示了如何使用适配器模式将QuickSort类和BinarySearch类的排序和查找功能适配到DataOperation接口中,实现算法的解耦和复用。
16 1
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
|
26天前
|
C语言
C语言中的math库概述
C语言中的math库概述
|
1月前
|
编译器 程序员 C语言
C语言 宏
C语言 宏
30 5
|
19天前
|
存储 Serverless C语言
C语言中的标准库函数
C语言中的标准库函数
17 0
|
19天前
|
API 开发工具 C语言
C语言与图形界面:利用GTK+、Qt等库创建GUI应用。
C语言与图形界面:利用GTK+、Qt等库创建GUI应用。
47 0
|
2月前
|
Linux C语言
C语言宏IS_REACHABLE
C语言宏IS_REACHABLE
21 1
|
3月前
|
Java C语言 C++
定义C语言的int main()函数
定义C语言的int main()函数
|
3月前
|
存储 移动开发 C语言
技术心得记录:嵌入式开发中常用到的C语言库函数
技术心得记录:嵌入式开发中常用到的C语言库函数
34 1
|
3月前
|
存储 C语言
C语言标准库介绍:<time.h>
C语言标准库介绍:<time.h>