C功能指针行为

Mat*_*att 2 c function-pointers

对于一个类,我正在编写一个简单的crypt函数.一切都按预期工作:

int crypt(char *key, int (*callback)(int, char*, int, int))
{
    int c, i = 0, n = strlen(key);
    while((c = fgetc(stdin)) != EOF)
    {
        // only change the char if it's printable
        if(c >= 32 && c <= 126)
            c = callback(c, key, n, i);

        fputc(c, stdout);
        i++;
    }
}

int encryptCallback(int c, char *key, int n, int i)
{
    return (c - 32 + key[i % n]) % 95 + 32;
}
int decryptCallback(int c, char *key, int n, int i)
{
    return (c - 32 - key[i % n] + 3 * 95) % 95 + 32;
}
Run Code Online (Sandbox Code Playgroud)

使用教授的测试用例,一切正常.但是当我最初编写回调时,我忽略了返回.它们的编码如下:

int encryptCallback(int c, char *key, int n, int i)
{
    c = (c - 32 + key[i % n]) % 95 + 32; // no return
}
int decryptCallback(int c, char *key, int n, int i)
{
   c = (c - 32 - key[i % n] + 3 * 95) % 95 + 32; // no return
}
Run Code Online (Sandbox Code Playgroud)

当我使用非返回的回调运行代码时,在我应用测试用例时输出仍然正确(是的,我重新编译,我没有运行旧代码).我用-Wall编译时只注意到'错误'.

所以我很困惑.为什么c(in crypt())在分配给返回值后得到正确的值callback(当回调没有返回任何东西时)?c它不是一个指针,它只是一个常规的int.

PS 赋值与函数指针无关.

caf*_*caf 7

如果调用者尝试使用函数的返回值,则无法return在具有非void定义行为的返回类型的函数中使用.

在这种情况下,您显然得到的未定义行为是"它返回了我想要的值,无论如何".你刚刚(非)幸运.(但它与函数指针无关).


如果你在x86上进行编译,那么它产生的根本原因是大多数x86调用约定指定int%eax寄存器中返回type的返回值.在您的情况下,编译器还决定使用此寄存器来计算新值c- 因此恰好将该值重新显示为"返回值".如果你在计算后在函数中做了一些更多的计算c,你会看到别的东西.