Поддерживается ли порядок операций, когда функция встроена в C компилятором, например, G CC? - PullRequest
0 голосов
/ 24 марта 2020

Рассмотрим следующий код:

#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

1 Ответ

1 голос
/ 24 марта 2020

Я предположил, что в определении Howevverf2 (), поскольку функция ничего не возвращала, компилятор неявно добавил return 0; в конце.

Это неверно. Согласно стандарту C, если программа пытается использовать значение вызова функции, но функция не использует return для возврата значения, поведение не определено (C 2018 6.9.1 12). (За исключением того, что main является особенным, правило в 5.1.2.3 1 говорит, что по умолчанию оно возвращает ноль.)

Однако, почему такое поведение не происходит с f ()?

Было замечено, что G CC ведет себя следующим образом: если в непустой функции нет оператора return, он возвращает значение последнего вычисленного выражения. Я не видел этого документированного, и вы не должны полагаться на это поведение. (Отчасти потому, что это правило неполное. Например, если последнее выражение имеет тип double, а тип возвращаемого значения - int, мы не ожидаем, что правило будет выполнено.)

В этом случае это поведение заставляет f или f1 возвращать три, потому что последнее выражение, оцененное в нем, является printf("foo");, а значение вызова printf является количеством напечатанных символов, которое в данном случае равно трем.

...