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



我想知道当我使用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是什么意思?

程序返回一个指针。它不是一个"数组",因为你把它放在问题中。因为数组的名称计算结果为其第一项的地址(与数组本身的地址相同)。

在C语言中,从main函数返回的值被解释为退出状态,即在您的示例中使用的$?变量。

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

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

现在让我们通过打印变量的地址和地址模256:

来修改程序
#include <stdio.h>
int main(void) {
    static int x[3];
    printf("%ld ==> %dn", (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,正如官方文档中所记录的那样。

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

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

更有可能的是,构造是错误的,你的实现只是忽略了这种情况;它只是编译代码,让机器指令做它们可能做的事情。要理解实际的行为,你必须理解在那个层次上发生了什么。

很可能,返回的指针本身的按位表示形式被解释为整数终止状态值,转换为操作系统退出码56。(可能值中的某些位域,例如最低的8位,是56)。这是假设int *int以相同的方式从函数返回。他们可能不会。例如,在摩托罗拉68000系列处理器的C编译器中,存在通过A0寄存器返回指针和D0中的整数值的惯例。因此,如果编写int *返回函数以满足对期望返回int的东西的外部引用,则调用者将接收碰巧在D0中的任何垃圾,而指针已经进入A0。

因为行为没有定义,所以不需要诊断!在C语言中,您甚至可以这样写:

int main[42] = { 3 };

在某些环境中将编译和链接。当执行时,数组数据最终用作机器语言函数映像。在IOCC:国际混淆C竞赛中,一个依赖于这个技巧的程序出现过一次(也许不止一次)。

相关内容

  • 没有找到相关文章

最新更新