C: преобразование типов при передаче аргумента вызову функции

При использовании Python 2.5 или позже, , uuid модуль уже включен с распределением стандарта Python.

Исключая:

>>> import uuid
>>> uuid.uuid4()
UUID('5361a11b-615c-42bf-9bdb-e2c3790ada14')

15
задан Midnight Blue 21 August 2009 в 20:30
поделиться

4 ответа

Приведения не имеют значения, имеет значение (возможно, неявный) прототип.

void foo(short s) {
    // do something
}

int main(void) {
  signed char c = 'a';

  foo(c);  // c is promoted to short by explicit prototype
  bar(c);  // c is promoted to int by implicit prototype
}

void bar(int i) {
    // do something
}

Когда в книге говорится, что «аргумент вызова функции является выражением», это означает, что правила продвижения одного и того же типа применять. Это будет легче понять, если вы подумаете об аргументе функции как о неявном присвоении переменной, указанной в прототипе функции. например, в приведенном выше вызове foo () есть неявное short s = c .

Вот почему приведение типов не имеет значения. Рассмотрим следующий фрагмент кода:

signed char c = 'a';
int i = (short) c;

Здесь значение c повышается сначала до short (явно), затем до int (неявно). Значение i всегда будет int .

Что касается char и short становится int , а float становится double , что относится к типам по умолчанию для прототипов неявных функций. Когда компилятор видит вызов функции до того, как он увидел либо прототип, либо определение функции, он автоматически генерирует прототип. По умолчанию используется int для целочисленных значений и double для значений с плавающей запятой.

Если конечное объявление функции не соответствует неявному прототипу, вы получите предупреждения.

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

Если конечное объявление функции не соответствует неявному прототипу, вы получите предупреждения.

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

Если конечное объявление функции не соответствует неявному прототипу, вы получите предупреждения.

19
ответ дан 1 December 2019 в 01:05
поделиться

У вас есть общее представление о том, что не так, но не совсем.

Произошло следующее: когда вы написали

function_call(c, number);

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

16
ответ дан 1 December 2019 в 01:05
поделиться

Компилятор жалуется, что он предположил, что function_call является функцией, возвращающей int, как указано в стандарте, а затем вы говорите, что это функция void. Компилятор не заботится об аргументах, если вы явно не объявляете, что они отличаются от фактической функции. Вы можете передавать ему без аргументов, и он не будет жаловаться.

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

2
ответ дан 1 December 2019 в 01:05
поделиться

Все упустили одну вещь. В ISO C прототип ISO-синтаксиса переопределяет продвижение аргументов по умолчанию.

И в этом случае компилятору разрешается генерировать другой код (!) исключительно на основе стиля определения. Это обеспечивает совместимость с K&R, но вы не всегда можете выполнять вызовы между языковыми уровнями, если вы не написали код ISO, как ожидает K&R, или изменили код K&R, чтобы увидеть прототипы ISO.

Попробуйте с cc -S -O. ..

extern float q; void f(float a) { q = a; }
movl    8(%ebp), %eax
movl    %eax, q

extern float q; void f(a) float a; { q = a; } // Not the same thing!
fldl    8(%ebp)
fstps   q
2
ответ дан 1 December 2019 в 01:05
поделиться
Другие вопросы по тегам:

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