如何解决为什么输出正确并带有注释返回
最近我一直在使用 Codility 进行锻炼,并且成功完成了 Passing Cars 练习。
#include <stdio.h>
int PassingCars(int someArray[],int N)
{
if(N == 1)
return 0;
int counter = 0,result = 0;
for(int i = 0; i < N; i++)
{
if(someArray[i] == 0)
++counter;
if(someArray[i] == 1)
{
result += counter;
if(result > 1e9)
return -1;
}
}
//return result;
}
int main()
{
int arrOne[] = {0,1,1};
printf("%d\n",PassingCars(arrOne,sizeof(arrOne)/sizeof(arrOne[0])));
return 0;
}
即使结果的返回被注释,输出也是正确的。怎么样?
解决方法
您的 CPU 不关心缺少“返回”
要执行 C 程序,其 source code 必须由 compiler 编译/翻译为 machine code。
机器代码只是一堆instruction that the CPU can execute一个接一个, 导致 registers 的值或内存位置发生变化。 当这些执行的一部分应该将值移交给另一部分时, 随后执行,它必须通过寄存器传递这些值。 但是当“返回值寄存器”没有设置时,我可能会包含一些先前指令结果的随机值。您的 CPU 不关心两个代码段之间缺少的切换,因为它只关心一条一条的执行指令,而不知道这些指令的更大逻辑是什么。
在您的情况下,这种寄存器中的旧值恰好与结果应该在 PassingCars
中设置/返回的值相同。可能是因为您有计算输入数组长度的代码,并且在执行过程中经常使用该值,这实际上是要返回的函数的正确结果。
要检查这一点,您可以将源代码编译为汇编代码并对其进行逆向工程:
$ gcc -S ./main.c
$ cat ./main.s
.file "main.c"
.text
.globl PassingCars
.type PassingCars,@function
PassingCars:
.LFB0:
.cfi_startproc
endbr64
.
.
.
但这相当耗时。
使用编译器警告避免丢失返回值
为避免将来出现此类问题,您可以使用编译器警告,例如 -Wall
:
gcc -Wall ./main.c
./main.c: In function ‘PassingCars’:
./main.c:23:1: warning: control reaches end of non-void function [-Wreturn-type]
23 | }
| ^
这是有关 gcc warning options 的文档的链接。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。