Продвижения параметра по умолчанию в вызовах функции C

http://ecx.images-amazon.com/images/I/519J3P8ANML._SL500_AA240_.jpg

Взял мое программирование к совершенно новому уровню.

30
задан Andrew Keeton 10 August 2009 в 16:08
поделиться

3 ответа

Вместо этого вам нужно использовать TlbExp , TlbExp - это инструмент, используемый для экспорта управляемых классов в COM, он прочитает сборку, найдет тип ComVisible и зарегистрирует их.

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

Что касается того, когда вступают в силу продвижение по умолчанию: используются продвижение аргументов по умолчанию именно тогда, когда ожидаемый тип аргумента неизвестен , , то есть когда нет прототипа или когда аргумент является вариативным.

33
ответ дан 27 November 2019 в 23:17
поделиться
  • (Безвариантные) параметры для функций с прототипом преобразуются в соответствующий тип, который может быть char, short, float.

  • Параметры для функций без прототипа и вариативных параметров подлежат продвижение аргументов по умолчанию.

Если вы определяете функцию с прототипом и используете ее без прототипа или наоборот, и у нее есть параметры типа char, short или float, у вас, вероятно, возникнут проблемы во время выполнения. У вас будут такие же проблемы с вариативными функциями, если продвинутый тип не соответствует тому, что используется при чтении списка аргументов.

Пример 1: проблема при определении функции с прототипом и использовании его без.

definition.c

void f(char c)
{
   printf("%c", c);
}

use.c

void f();

int main()
{
   f('x');
}

может завершиться ошибкой, потому что будет передано int, а функция ожидает char.

Пример 2: проблема при определении функции без прототипа и использовании ее с ним.

definition.c

void f(c)
   char c;
{
   printf("%c", c);
}

(Это определение очень старомодно)

use.c

void f(char c);

int main()
{
   f('x');
}

может завершиться ошибкой, потому что ожидается int но будет передан символ.

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

33
ответ дан 27 November 2019 в 23:17
поделиться

Ваше замешательство происходит из-за очень небольшого непонимания терминологии - как объявления, так и определения могут включать прототипы (или нет):

void func(int a, char b, float c);

Это объявление функции , , которое включает прототип.

void func(int a, char b, float c) { /* ... */ }

Это определение функции , которое включает прототип.

«Прототипированный» и «не прототипированный» - это просто атрибуты функции типа , и оба объявления и определения представляют тип функции.

Таким образом, вы можете иметь объявление без прототипа:

void func();

или вы можете иметь определение без прототипа (стиль K&R C):

void func(a, b, c)
    int a;
    char b;
    float c;
{ /* ... */ }
15
ответ дан 27 November 2019 в 23:17
поделиться
Другие вопросы по тегам:

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