c - C函数的有趣返回行为

标签 c return return-value return-type

<分区>

我有一个函数,它以 char 数组的形式进行数学运算,返回一个 int 结果(这一切都有效,并且纯粹是为了上下文,与问题无关)。

当然,我的函数定义是:int calc(char* operation) {},它期望返回一个 int。

在解析字符串以确定操作数和要执行的操作后,我将结果分配给一个变量。我刚刚意识到我忘记将 return 语句放在函数中,但我仍然得到正确的结果......

这是函数。我最初忘记了最后一行。

// Function to return int results of operation specified in char* (argv[1])
int calc(char* operation)
{
    int op_index = 0;
    int end_index = 0;
    for (int i = 0; i < 128; i ++)
    {
        if ((operation[i] < 48 || operation[i] > 57) && op_index == 0)
            op_index = i;
        if (operation[i] == '\0')
        {
            end_index = i;
        i = 128;
        }
    }

    int opa = 0;
    int opb = 0;
    for (int i = 0; i < op_index; i ++)
        opa += (operation[i]-48)*power(10, op_index - (i+1));
    for (int i = op_index+1; i < end_index; i ++)
        opb += (operation[i]-48)*power(10, end_index - (i+1));

    int res = 0;
    if (operation[op_index] == '+')
        res = opa + opb;
    else if (operation[op_index] == '-')
        res = opa - opb;
    else if (operation[op_index] == '*')
        res = opa * opb;
    else if (operation[op_index] == '/')
        res = opa / opb;
    else if (operation[op_index] == '%')
        res = opa % opb;

    // This is the line that I had forgotten... but still got the right results when calling this function
    return res;
}

有人对此有解释吗?我的猜测是它默认返回最后一个函数调用的结果,这是正确的,因为最终语句的 if/else 结构。

谢谢!

最佳答案

技术上未定义的行为。

如果这是 x86 Intel,可能发生的情况是在从函数返回之前执行的数学运算恰好将预期的返回值留在 EAX 寄存器中。对于返回整数的函数,EAX 寄存器也是将返回值传递回调用者的方式。

calc 函数的尾部生成了如下所示的程序集:

    int res = 0;
 mov         dword ptr [res],0  
    if (operation[op_index] == '+')
 mov         eax,dword ptr [operation]  
 add         eax,dword ptr [op_index]    // MATH OPERATION WINDS UP IN EAX REGISTER
 movsx       ecx,byte ptr [eax]  
 cmp         ecx,2Bh  
 jne         calc+149h (05719F9h)  

然后像这样调用代码:

int x;
x = calc((char*)"4+5");
printf("%d\n", x);

生成的程序集是这样的

    x = calc((char*)"4+5");
 push        offset string "4+5" (0E87B30h)  
 call        _calc (0E8128Ah)  
 add         esp,4  
 mov         dword ptr [x],eax   // TAKE EAX AS RESULT OF FUNCTION AND ASSIGN TO X

但是当我将项目设置从调试构建切换到优化零售时,所有的赌注都被取消了。编译器和链接器将开始内联汇编,进行疯狂的优化等......它甚至会围绕函数不返回任何东西的事实进行优化......事实上,它会在 printf 语句提示 x 未初始化,即使它已明确分配给 calc 的结果。

所以简短的回答是你走运了。但我想指出为什么它“恰好有效”。

关于c - C函数的有趣返回行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54990585/

相关文章:

国际象棋滑动件位板

java - 尽管我有一个 Eclipse 要求返回声明

powershell - 寻求对 Powershell ExpandProperty 行为的解释

javascript - 无法从 Promise 中获取值(value)

c - 在c中执行时正则表达式不起作用

c - gdb如何检测pthread?

c - 通过 `extern` 变量访问 .text 段是否会导致未定义的行为?

尝试在 java static 中打印矩阵值时出现 java.lang.NullPointerException

c++ - 从指向数组的函数返回指针时出错

android - 如何将所选项目从 ListActivity 返回到另一个 Activity?