Нет определенного типа параметра функции по умолчанию для int? Я сошел с ума?

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

#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;
}

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

Ответ 1

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

void foo(n) 
    int n; 
{

}

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

Ответ 2

Ответ на

@Erik верен, но (ИМО) можно было бы неправильно понять.

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

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

int foo(n)
int n;
{
}

I.e. определение стиля K & R по-прежнему разрешено, но вам нужно указать тип возвращаемого значения и тип параметра, даже если тип является int.

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

int foo(int n) {}

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

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

Ответ 3

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