Неявное объявление int переменной, когда спецификатор типа указан [duplicate]

Подумайте об этом так, каждый раз, когда вы видите стрелку, вы заменяете ее на function. function parameters определены перед стрелкой. Итак, в вашем примере:

field => // function(field){}
e => { e.preventDefault(); } // function(e){e.preventDefault();}

, а затем вместе:

function (field) { 
    return function (e) { 
        e.preventDefault(); 
    };
}

Из документов :

// Basic syntax:
(param1, param2, paramN) => { statements }
(param1, param2, paramN) => expression
   // equivalent to:  => { return expression; }

// Parentheses are optional when there's only one argument:
singleParam => { statements }
singleParam => expression

3
задан Keith Thompson 22 November 2011 в 02:59
поделиться

3 ответа

K & amp; R2 охватывает версию языка 1989/1990. В действующем стандарте ISO C, опубликованном в 1999 году 2011 года, исключается правило «неявное int» и требуется видимое объявление для любой функции, которую вы вызываете. Компиляторы не обязательно применяют это по умолчанию, но вы должны иметь возможность запрашивать более строгие предупреждения - и вам определенно нужно.

Пример: стандартная функция sqrt() объявлена ​​в <math.h>:

double sqrt(double);
.

Пример: стандартная функция sqrt() объявлена ​​в <math.h>:

double sqrt(double);
]

Если вы пишете вызов без , требуемый #include <math.h>:

double x = 64.0;
double y = sqrt(x);

компилятор C90 будет предположить , что sqrt вернется int - и он сгенерирует код для преобразования результата с int в double. Результатом будет мусор или, возможно, сбой.

(Вы могли вручную объявить sqrt самостоятельно, но это неправильное решение.)

So не делайте этого. Всегда включайте любой заголовок, необходимый для любой вызываемой вами функции. Вы можете уйти с вызовом необъявленной функции, если она возвращает int (и если ваш компилятор не применяет строгую семантику C99 или C11, и если выполняется несколько других условий), но для этого нет веских оснований.

Понимание правила «неявного int» по-прежнему полезно для понимания поведения старого или плохо написанного кода, но вы никогда не должны зависеть от него в новом коде.

10
ответ дан Keith Thompson 18 August 2018 в 08:32
поделиться

Просто говорится, что если компилятор встречает код, вызывающий неизвестную функцию, то он неявно рассматривает его так, как будто он уже видел заявленный прототип формы int unknown();

0
ответ дан R. Martinho Fernandes 18 August 2018 в 08:32
поделиться
  • 1
    неправильно. он возвращает int по умолчанию – perreal 22 November 2011 в 02:35
  • 2
    Вы даже прочитали текст, цитируемый? – R. Martinho Fernandes 22 November 2011 в 02:35
  • 3
    @TJD: В чем смысл этого, и когда можно это встретить? Не могли бы вы привести пример? – Matthew Hoggan 22 November 2011 в 02:36
  • 4
    Текст читает & quot; ... и ничего не принимается в отношении его аргументов. & Quot ;, но (void) означает, что "принимает никакие аргументы & quot ;. Это отличается от (). – R. Martinho Fernandes 22 November 2011 в 02:38
  • 5
    Да, скажем, у вас есть файл 1, содержащий вызов типа x = foo () ;, но вы не включили заголовочный файл, который объявляет форматы типов для foo, а foo реализуется в файле 2. Когда компилятор генерирует сборку код для файла 1, он должен сделать предположение о том, как сгенерировать код вызова для foo и обрабатывать возвращаемые параметры. Предположение, которое он выбирает: 1) ничего не делать с входными аргументами и 2) return type is int – TJD 22 November 2011 в 02:40

Прототипы функций были введены на язык позже.

Перед прототипами компилятор предположил, что каждый аргумент, переданный каждой неизвестной функции, должен быть передан как целое число, и предположил бы, что возвращаемое значение также было integer.

Это работало отлично для тех немногих случаев, когда это было правильно, но означало, что людям приходилось писать программы в неудобном порядке, чтобы функции никогда не полагались на неизвестные функции, которые не соответствуют этому ожиданию.

Когда прототипы были введены в C89 (aka ANSI C или ISO C), прототипы позволяют компилятору точно знать, какие типы аргументов ожидаются и какие типы результатов будут возвращены.

Настоятельно рекомендуется использовать прототипы функций для всего нового кода; при работе с полностью старой базой кода прототипы могут быть вредными. (Или, если код должен быть скомпилирован в компиляторе pre-ANSI C, то вы можете отказаться от прототипов, чтобы он мог быть построен на древнем программном обеспечении. gcc - единственное место, которое я видел это в долгое время.)

7
ответ дан sarnold 18 August 2018 в 08:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: