为什么Linux系统调用返回types“长”?

我正在阅读Linux Kernel Development ,3rd ed。,了解内核实现和devise。 第5章是关于系统调用。 作者展示了一个使用SYSCALL_DEFINE0macros定义的系统调用声明的示例,该macros在该特定示例中展开为:

 asmlinkage long sys_getpid(void) 

他进一步说:

[…]为了兼容32位和64位系统,定义在用户空间中返回int的系统调用在内核中返回一个long。

他并没有比这更深,我也不明白为什么这样。 为什么long使用32位和64位系统? 为什么我们不能返回一个简单的int

因为在常见的GCC编译器sizeof(int)==4sizeof(void*)==8 && sizeof(long)==8 ;的许多64位机器(如x86-64) 这就是所谓的I32LP64(或只是LP64) 数据模型

例如,在Linux / x86-64系统上编译并运行以下程序:

 #include<stdio.h> #include<stdint.h> int main () { printf ("sizeof(int)=%d\n", (int) sizeof (int)); printf ("sizeof(intptr_t)=%d\n", (int) sizeof (intptr_t)); printf ("sizeof(short)=%d\n", (int) sizeof (short)); printf ("sizeof(long)=%d\n", (int) sizeof (long)); printf ("sizeof(long long)=%d\n", (int) sizeof (long long)); printf ("sizeof(void*)=%d\n", (int) sizeof (void *)); return 0; } 

在我的系统上使用gcc -Wall sc -os编译并在我的Debian / Sid / x86-64( i3770k处理器, GCC ./s上运行./s

 sizeof(int)=4 sizeof(intptr_t)=8 sizeof(short)=2 sizeof(long)=8 sizeof(long long)=8 sizeof(void*)=8 

使用gcc -m32 -Wall sc -o s32编译成32位模式并运行./s32

 sizeof(int)=4 sizeof(intptr_t)=4 sizeof(short)=2 sizeof(long)=4 sizeof(long long)=8 sizeof(void*)=4 

如果使用gcc -mx32 -O3 -Wall sc -o sx32编译x32,我会得到相同的输出!

顺便说一句,也许更好的问题是为什么不使用intptr_t ….我不知道(可能是一个习惯的问题; 当Linus第一次开始编写他的内核, C99标准 – 定义<stdint.h>intptr_t不存在)。

阅读更多关于ABI的信息 ,特别仔细阅读X86-64 ABI (另请参阅x32 ABI …)以及x86调用约定上的wikipage。