C 为什么我们使用显式数据类型?(从低层次的角度)

C 为什么我们使用显式数据类型?(从低层次的角度),c,types,x86,language-design,low-level,C,Types,X86,Language Design,Low Level,当我们看一些基本数据类型时,比如char和int,我们知道char只是一个无符号字节(取决于语言),int只是一个有符号的dword,bool只是一个只能为1或0的字符,等等。我的问题是,为什么我们在编译语言中使用这些类型,而不是仅仅声明一个byte类型的变量,dword等,因为应用于上面提到的类型的操作几乎都是相同的,一旦您区分了有符号和无符号数据以及浮点数据 为了扩展问题的上下文,在C语言中,if和while语句可以将布尔值作为输入,该值通常存储为字符,这就不需要显式布尔类型 实际上,这两段

当我们看一些基本数据类型时,比如char和int,我们知道char只是一个无符号字节(取决于语言),int只是一个有符号的dword,bool只是一个只能为1或0的字符,等等。我的问题是,为什么我们在编译语言中使用这些类型,而不是仅仅声明一个byte类型的变量,dword等,因为应用于上面提到的类型的操作几乎都是相同的,一旦您区分了有符号和无符号数据以及浮点数据

为了扩展问题的上下文,在C语言中,if和while语句可以将布尔值作为输入,该值通常存储为字符,这就不需要显式布尔类型

实际上,这两段代码在二进制级别应该是等效的:

int main()
{
    int x = 5;
    char y = 'c';
    printf("%d %c\n", x - 8, y + 1);
    return 0;
}

//outputs: -3 d
-

我的问题是,为什么我们在编译语言中使用这些类型

使代码目标不可知。某些平台只有有效的16位整数,强制变量始终为32位会使代码在为此类平台编译时毫无理由地变慢。或者您有一个36位整数的目标,而严格的32位类型需要额外的指令来实现

您的问题听起来非常以x86为中心。x86并不是唯一的体系结构,对于大多数语言来说,设计人员并没有想到一种语言


甚至在x86在台式机和服务器上广泛使用的时代设计的更新语言也被设计为可移植到其他ISA,如8位AVR,其中32位
int
需要4个寄存器,而16位
int
需要2个寄存器。编程语言定义了一个“抽象”数据模型,计算机设计师可以自由地实现他的方式。例如,没有任何东西要求将布尔值存储在一个字节中,它可以与其他字节一起“打包”为单个位。如果仔细阅读C标准,您会注意到字符没有定义的大小

[有趣的是,我想起了一个古老的时代,当时FORTRAN变量,包括整数、浮点数和布尔数,存储在IBM机器上的72位上。]

语言设计者应该在机器架构上设置一些限制,为优秀的设计留下机会。事实上,语言没有“低级”,它们隐含地描述了一个不与特定硬件绑定的虚拟机(它可以用齿轮和绳索实现)

据我所知,只有ADA语言详细说明了算法的所有特征,但没有强制每个字执行一定数量的位


忽略布尔类型是C语言中最悲哀的设计决策之一。我最晚花了C99来集成它:-(


另一个可悲的决定是不再将int类型视为自然适合机器字的类型(在当前的PC中应该是64位)。

高级语言的目的是提供与机器细节的某种隔离。因此,我们称之为“整数”,而不是特定数量的内存字节。然后,实现将高级类型映射到最适合目标硬件的任何类型上

不同的4字节类型有不同的语义:对于整数,有符号和无符号对于某些类的程序很重要

我理解这是一个C问题,关于C的级别有多高还有争议;但它至少旨在跨机器体系结构进行移植

在您的示例中,假设“int”是32位。语言中没有任何规定必须是真的。它并不总是真的,而且在最初的PDP-11实现中肯定不是真的。例如,现在,在64位机器上,将“int”设为64位可能是合适的


请注意,语言具有“integer”等类型并不是一成不变的。BLISS是一种与C具有相同概念级别的语言,其唯一的内置数据类型是机器字。

您所说的“dword”是什么意思?因此您具体指的是x86双字,而不是MIPS或PowerPC(其中一个字为32位).然后标记x86.嗯,有36位单词,所以是“双单词”如果
x
仅声明为
dword
,您或编译器如何知道它是
int
无符号int
浮点
、指向
结构foo
的指针还是其他指针?对于代码
x-8
,编译器是否应加载
x
、一个integer 8,然后执行整数减法,还是应该加载
x
,浮点8,然后执行浮点减法?此外,字符不被假定为有符号或无符号。我相信默认值取决于编译器实现,而不是标准值。这可能会随着时间的推移而发生变化。这至少是为什么会有无符号字符和无符号字符char就像有一个无符号的int和一个int。为什么您希望一个
int
数组在64位CPU上浪费两倍的内存带宽/缓存占用空间?并且在x86-64上需要更多的机器代码字节作为REX前缀。对于
长的
来说,与寄存器一样宽更常见。您的程序不能依赖
int
如果您想编写完全可移植的代码,则其宽度可以超过16位,因此在某些目标上使其超宽没有什么好处。@PeterCordes:我应该说“可以”而不是“应该”。(顺便说一下,人们可能会考虑将寄存器和ALU宽度增加到64位的有用性,主要是为了扩大地址空间)。定义int大小的决定权属于实现者。如果32位被认为是有效的,那么32位。但随着int成为事实上的32位,最初的意图就失去了。我们肯定需要64位数字作为时间戳和各种其他东西,而不仅仅是指针计算。以及扩展精度inte
signed dword main()
{
    signed dword x = 5;
    byte y = 'c';
    printf("%d %c\n", x - 8, y + 1);
    return 0;
}

//outputs: -3 d