C:main()返回一个数组总是等于56

时间:2016-10-08 13:55:46

标签: c shell main exitstatus

我想知道当我使用main函数的返回值时会发生什么。

我发现如果我从main返回一个数组变量(它应该是退出状态)并在shell中打印退出状态,那么输出总是56.我想知道为什么?

C程序:

int* main(void) {
    static int x[3];
    x[0]=89;
    x[1]=15;
    x[2]=10;
    return x;
} 

我按如下方式测试:

gcc array_return.c -o array_return
./array_return
echo $?

即使更改数组的大小或更改数组中的数字,输出也始终为56。数字56的含义是什么?

2 个答案:

答案 0 :(得分:5)

你的程序返回一个指针。它不是"数组"正如你在问题中提出的那样。因为数组的名称求值为其第一项的地址(与数组本身的地址相同)。

在C中,main函数返回的值被解释为exit status,即您示例中使用的$?变量。

我想,你正在运行Bash shell,因为在Bash中,退出状态存储在$?变量中。指针通常是一个大数字,至少大于 255 ,这是最大exit code in Bash

  

超出范围退出值可能导致意外退出代码。出口   大于255的值返回模256的退出代码。例如,   退出3809给出退出代码225(3809%256 = 225)。

现在让我们通过打印变量的地址和地址modulo 256 修改您的程序:

#include <stdio.h>

int main(void) {
    static int x[3];
    printf("%ld ==> %d\n", (size_t)x, (size_t)x % 256);
    return (int)x;
}

让我们编译并测试我是否正确:

$ gcc -Wall -g test.c -o test && ./test; echo $?
test.c: In function ‘main’:
test.c:6:12: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     return (int)x;
            ^
6295620 ==> 68
68

正如我们所看到的,返回状态等于6295620 % 256,因为它在official documentation中有记录。

答案 1 :(得分:2)

根据ISO C,int* main(void)不是实现需要支持的启动函数main的形式之一。因此,行为不是由语言标准定义的。

int *main(void)可以作为C实现提供的文档扩展。通过这种方式,C实现可以支持编写启动函数的其他方法。

更可能的是,构造是错误的,你的实现只是忽略了这种情况;它只是编译代码并让机器指令尽其所能。要了解实际行为,您必须了解该级别的情况。

很可能,返回的指针本身的按位表示被解释为整数终止状态值,转换为操作系统退出代码56.(可能是值中的某个位域,例如作为最低的8位,是56)。这假设int *int以相同的方式从函数返回。他们可能不是。例如,在Motorola 68000系列处理器的C编译器中,存在通过A0寄存器返回指针和D0中的整数值的约定。因此,如果编写int *返回函数以满足对预期返回int的内容的外部引用,则调用程序将接收D0中发生的任何垃圾,而指针已进入A0。 / p>

由于未定义行为,因此无需进行诊断!在C语言中,您甚至可以写下这个:

int main[42] = { 3 };

在一些将编译和链接的环境中。执行时,阵列数据最终用作机器语言功能图像。 IOCC中出现了一次依赖此技巧的程序(可能不止一次):国际混淆C大赛。

相关问题