当编译器(例如,GCC)在C中内联函数时,是否保持操作顺序?

问题描述 投票:-5回答:1

请考虑以下代码:

#include <stdio.h>

int f1() {
    printf("foo");
}

int f2() {
    int a;
}

int main() {
    int a = f1(), b = f2();

    printf("\n%d\n", a);
    printf("\n%d\n", b);

    return 0;
}

如果内联函数,则输出符合预期:

foo
3

0

但是,在以下情况下

#include <stdio.h>

int f() {
    printf("foo");
    int a;
}

int main() {
    int a = f();
    printf("\n%d\n", a);

    return 0;
}

输出为

foo
3

而不是

foo
0

即使最后一条语句不返回任何内容。我假设在Howevver f2()的定义中,因为该函数未返回任何内容,所以编译器在末尾隐式添加了return 0;。但是,为什么f()不会出现这种现象?

我使用以下代码进行编译:

gcc -O0 a.c -o a.out
c gcc compiler-optimization
1个回答
0
投票

我假设在Howevverf2()的定义中,由于该函数未返回任何内容,因此编译器会隐式添加一个返回值0;最后。

这是不正确的。根据C标准,如果程序尝试使用函数调用的值,但该函数未使用return返回值,则未定义行为(C 2018 6.9.1 12)。 (除了main是特殊的,在5.1.2.3 1中的规则说它确实默认返回零。)

但是为什么在f()中不会出现这种现象?

已经观察到,GCC似乎以这种方式运行:如果函数中没有return语句,它将返回最后一个求值表达式的值。我没有看到此文档,这不是您应该依靠的行为。在这种情况下,它使ff1返回三个,因为其中计算的最后一个表达式为printf("foo");,并且printf调用的值为打印的字符数,在这种情况下为三个。

© www.soinside.com 2019 - 2024. All rights reserved.