Нет определенного типа параметра функции по умолчанию int?Я сумасшедший? - PullRequest
9 голосов
/ 04 мая 2011

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

#include <stdio.h>

char toChar(n) {
  //sizeof n is 4 on my 32 bit system
  const char *alpha = "0123456789ABCDEF";
  return alpha[n];
}

int main() {
  putchar(toChar(15)); //i.e.
  return 0;
}

Я уверен, что main по умолчанию использует int по умолчанию для большинства компиляторов некоторого стандарта (но только с возвратом), это поведение также верно для других функций или эта реализация определена? Кажется, это просто необычно, мой компилятор - просто немного устаревший порт GCC (MinGW).

Ответы [ 3 ]

13 голосов
/ 04 мая 2011

Объявление функции в стиле K & R:

void foo(n) 
    int n; 
{

}

Если тип не указан, по умолчанию используется int. Это действительно в C89, а не в C99

5 голосов
/ 04 мая 2011

@ Эрик отвечает правильно, но (IMO) может быть довольно легко неправильно понято.

То, что у вас есть, это определение стиля K & R, это полностью верно.Поскольку int считается типом по умолчанию, если у вас есть что-то вроде: foo(n) { }, это означает, что тип возвращаемого значения и тип n по умолчанию int.

C99 (в основном)удаляет правило «int по умолчанию», но не полностью удаляет определения стиля K & R.Это означает, что приведенное выше определение больше не допускается;чтобы определить foo с теми же типами, что и выше, вы все равно можете использовать:

int foo(n)
int n;
{
}

Т.е. определение стиля K & R все еще разрешено, но вы do должны указать возвращаемое значениеtype и параметр type, даже если тип int.

Однако этот стиль определения функции устарел (согласно §6.11.7).Это действительно только разрешено ради древнего (предварительно стандартного) кода.Вы не хотите писать новый код таким способом, хотя технически это все еще разрешено.Для нового кода вы явно хотите использовать определение в стиле прототипа:

int foo(int n) {}

Для тех, кто заботится о таких вещах, определение стиля K & R все еще используется в каком-то новом коде.Его более короткий стиль может быть полезен (используя термин «свободно») в коде-гольфе.

Пока мы на нем: ответ @ stijn также является своего рода правильным.В частности, когда функция определяется таким образом (т. Е. Стиль K & R), все аргументы подлежат продвижению по умолчанию.Это означает, что если вы передадите целочисленный тип, меньший int, он будет повышен до int, а если вы передадите float, он будет повышен до double.

0 голосов
/ 04 мая 2011

afaik это называется продвижение аргумента. я не помню точных правил, но все сводится к тому, что компилятору разрешено использовать int для аргументов, когда он (она?) еще не знает прототип функции.

...