Когда выполняется расчет приведения? - PullRequest
0 голосов
/ 02 февраля 2019

Я никогда не понимал, когда что происходит, когда дело доходит до кастинга.Я предполагаю, что неявное приведение происходит во время компиляции (поправьте меня, если я ошибаюсь), но как насчет этого:

int i = 0;

double d = sqrt((double)i);

Произойдет ли это во время компиляции / во время выполнения?

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

Зависит от оптимизации и архитектуры.Например, GCC с -O3 вообще пропустит вызов sqrt для некоторых значений, как видно здесь .

Если переменная неизвестна во время компиляции (т.е. еслион читается из файла или из пользовательского ввода), тогда нет никакого способа фактически вызвать sqrt с двойным значением i.На x86 для этого требуется инструкция, подобная CVTSI2SD (Преобразовать целочисленное двойное слово в скалярное значение с плавающей запятой двойной точности), как показано здесь .Компилятор создает эту инструкцию во время компиляции, но выполнение инструкции (очевидно) происходит во время выполнения.

0 голосов
/ 02 февраля 2019

Неважно и не указано (см. Стандарт C11 n1570 ).Помните о как-будто правиле.На самом деле это зависит от того, как ваш компилятор оптимизирует .

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

Если у вас есть GCC, скомпилируйте функцию с вашим кодомиспользуя gcc -O3 -S -fverbose-asm и загляните внутрь созданного файла ассемблера *.s.Вы будете удивлены.

В частности, с GCC 8 в Linux / Debian / x86-64, компиляция

// file dvep.c
#include <math.h>
int
main (void)
{
  int i = 0;
  double d = sqrt ((double) i);
  return 0;
}

с использованием команды gcc -O3 -S -fverbose-asm dvep.c создает файл dvep.sчья функция main уменьшена до:

    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
# dvep.c:9: }
    xorl    %eax, %eax  #
    ret 
    .cfi_endproc

, и вы увидите, что во время выполнения внутри main

не происходит операций с плавающей запятой
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...