Цикл while выполняется с неопределенным именем функции в качестве условия - PullRequest
4 голосов
/ 23 апреля 2019

Почему этот код выполняется?

#include <stdio.h>
int i();
int main(){
    while(i){printf("Hi");}
}

Какое значение i принимает цикл while?

Я попытался printf("%d", i), и он сказал, что iundefined, чего и следовало ожидать, поскольку он имеет только объявление, но почему while работает?

Ответы [ 2 ]

8 голосов
/ 23 апреля 2019

Если вы скомпилируете с включенными правильными предупреждениями, вы увидите

warning: the address of ‘i’ will always evaluate as ‘true’ [-Waddress]
     while(i){printf("Hi\n");}

Здесь в качестве адреса функции берется значение i, т. Е. Указатель на функцию.

Чтобы добавить немного контекста, из руководства по gcc ( выделение шахты )

-Waddress

Предупреждать о подозрительном использовании адресов памяти. К ним относятся с использованием адреса функции в условном выражении, таком как void func(void); if (func), , и сравнение с адресом памяти строкового литерала, такого как if (x == "abc"). Такое использование обычно указывает на ошибку программиста: адрес функции всегда оценивается как true, поэтому их использование в условном выражении обычно указывает на то, что программист забыл скобки в вызове функции; и сравнение со строковыми литералами приводит к Поведение не определено и не является переносимым в C, поэтому они обычно указывают, что программист намеревался использовать strcmp. Это предупреждение активируется -Wall.

0 голосов
/ 23 апреля 2019

У вас есть объявление функции int i();

Стандарт C11 (n1570) гласит: 6.3.2.1 / 4 :

Обозначение функции - это выражение с типом функции. За исключением случаев, когда это операнд оператора sizeof, оператора _Alignof или унарного оператора &, указатель функции с типом '' функция, возвращающая тип '', преобразуется в выражение с типом '' указатель на функцию, возвращающую тип ''.

Таким образом, i в while(i) является указателем на функцию, и, поскольку это адрес, он всегда будет иметь значение true.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...