Llvm 如果一个程序';s main返回一个i32,为什么是$?(由调用它的shell测量)被截断为8位?

Llvm 如果一个程序';s main返回一个i32,为什么是$?(由调用它的shell测量)被截断为8位?,llvm,llvm-ir,Llvm,Llvm Ir,很抱歉提出这样的问题,但为什么结果不是516 define i32 @main() { %1 = add i32 6, 500 %2 = add i32 5, 5 %3 = add i32 %1, %2 ret i32 %3 } i32是一个32位整数 用法: ./lli Program.ir; echo $? 4 提前感谢Unix中进程的退出代码只有8位。无论是否涉及LLVM,任何较大的值都会被截断: $ ( exit 51

很抱歉提出这样的问题,但为什么结果不是
516

define i32 @main()
{
        %1 = add i32 6, 500
        %2 = add i32 5, 5
        %3 = add i32 %1, %2
        ret i32 %3
}

i32是一个32位整数

用法:

./lli Program.ir; echo $?
4

提前感谢

Unix中进程的退出代码只有8位。无论是否涉及LLVM,任何较大的值都会被截断:

$ ( exit 516 ); echo $?
4
在类UNIX操作系统中,退出代码(我将区分程序返回的退出值和启动程序的进程可用的退出代码)实际上是几个不同项的组合,其中一个是退出值。例如,请参见,其中包含(带有我的重点
[额外信息]
):

不要混淆程序的退出状态
[value]
和进程的终止状态
[code]
。除了程序完成之外,还有很多方法可以终止进程。但是,如果进程终止是由程序终止引起的(即,
退出
),程序的退出状态
[value]
将成为进程终止状态
[code]
一部分

从进程获取实际退出状态的宏(请参阅)状态:

如果状态的
WIFEXITED
为真,则此宏将从子进程返回退出状态值的低位8位

Linux
exit_组的实际源代码也表明了这一点,它最终被
exit
调用:

SYSCALL_DEFINE1(exit_group, int, error_code)
{
    do_group_exit((error_code & 0xff) << 8);
    /* NOTREACHED */
    return 0;
}
换句话说,它还必须在进程退出代码中放入其他内容,例如哪个信号终止了它(如果它被信号终止),它是否转储了内核,等等。这就是为什么退出值被限制在比预期更小的范围内

ISO标准(C11)也允许这一点,在
7.22.4.4中,退出函数/5
(因为从
main()
返回整数值相当于使用该值调用
exit()

最后,控制返回到主机环境。如果状态值为零或
EXIT\u SUCCESS
,则返回状态成功终止的实现定义形式。如果状态值为
EXIT\u FAILURE
,则返回状态不成功终止的实现定义形式。其他ise返回的状态由实现定义。


我想读取输出的合理方法就是使用
put
?格式化和写入stdout绝对是最干净的方法
do_group_exit(ksig->info.si_signo)