为什么Linux系统调用返回类型" long"?

时间:2014-01-05 22:44:30

标签: c linux linux-kernel system-calls

我正在阅读 Linux Kernel Development ,第3版,以了解内核实现和设计。第5章是关于系统调用的。作者展示了使用SYSCALL_DEFINE0宏定义的系统调用声明的示例,该宏在该特定示例中扩展为:

asmlinkage long sys_getpid(void)

他进一步说:

  

[...]对于32位和64位系统之间的兼容性,定义为在用户空间中返回int的系统调用在内核中返回long。

他没有比这更深入,我不能完全理解为什么会这样。为什么使用long与32位和64位系统相关?为什么我们不能返回普通int

1 个答案:

答案 0 :(得分:11)

因为许多64 bits计算机(例如x86-64)用于公共GCC编译器sizeof(int)==4sizeof(void*)==8 && sizeof(long)==8;这称为I32LP64(或仅LP64)data model

例如,在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 s.c -o s在我的系统上进行编译并在我的Debian / Sid / x86-64(i3770k处理器GCC 4.8处理器when Linus上运行./s

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

在使用gcc -m32 -Wall s.c -o s32并运行./s32

以32位模式编译之后
sizeof(int)=4
sizeof(intptr_t)=4
sizeof(short)=2
sizeof(long)=4
sizeof(long long)=8
sizeof(void*)=4

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

顺便说一句,或许更好的问题是为什么不使用intptr_t ....我不知道(可能是习惯问题; C99首先开始编写他的内核,{{3标准 - 定义<stdint.h>intptr_t - 尚不存在。)

详细了解ABIs,特别请仔细阅读X86-64 ABI(另请参阅x32 ABI ...)和x86 calling conventions上的wikipage。