Я получаю предыдущее значение с плавающей запятой, когда печатаю новое значение

Я получаю вывод 0.23 со второго printf. Но приведение типов дает требуемый результат. Если я не использую приведение типов, печатается предыдущее значение. Версия компилятора GCC 6.3.

#include <stdio.h>

int main() {
    printf("%f ", 0.23);
    printf("%f", 0);
    return 0;
}

ССЫЛКА НА IDE


person Lelouch Yagami    schedule 14.03.2019    source источник
comment
Всегда полезно читать предупреждения компилятора.   -  person Artur    schedule 14.03.2019
comment
Включите больше предупреждений с помощью gcc -Wall -Wextra -Werror, компилятор предупредит вас о несоответствии типа аргумента.   -  person chqrlie    schedule 14.03.2019
comment
@LelouchTagami: вы можете принять один из ответов, нажав на серую галочку под его оценкой   -  person chqrlie    schedule 23.03.2019


Ответы (2)


in

> printf("%f",0);

Вы просите напечатать двойное число, но указываете целое число, это противоречит

Это не тот случай, когда сгенерированный код создает двойник из int, потому что printf не int printf(const char *, double);, а int printf ( const char * format, ... ); и компилятор не смотрит в формате, чтобы сделать необходимые преобразования (но во многих случаях компилятор предупреждает вас)

Когда prints доступ ко второму аргументу делается для получения двойного с использованием 64b и, возможно, ваш int использует только 32b, поведение не определено.


(отредактировать, спасибо @chqrlie)

Я получаю предыдущее значение с плавающей запятой, когда печатаю новое значение

В вашем случае может быть printf извлекает двойное значение из регистров MMX, а не значение int, которое было передано через стек или обычные регистры... что может объяснить, почему одно и то же значение печатается дважды. Но, конечно, как всегда с неопределенным поведением, в любой момент может произойти что угодно еще.

person bruno    schedule 14.03.2019

Проблема заключается в сочетании двух факторов:

Во-первых, для функций с переменным числом аргументов, таких как printf, компилятор не будет выполнять никаких неявных преобразований аргументов. Таким образом, 0 в списке аргументов является целочисленной константой (типа int).

Второй фактор — несоответствие спецификатора формата. Функция printf не знает ничего о передаваемых аргументах, кроме того, что указано в строке формата. Несоответствие формата и типа аргумента приводит к неопределенное поведение. И поскольку спецификатор "%f" заставляет printf ожидать значение типа double, а вы указали значение int, у вас такое несоответствие.

person Some programmer dude    schedule 14.03.2019
comment
@ Какой-то чувак-программист Когда я использовал GCC 4.3 в DevC++, я получал 0.00. Но в последней версии я не получаю. - person Lelouch Yagami; 14.03.2019
comment
@LelouchYagami Это неопределенное поведение в действии. Вам повезло, что он не вызвал носовых демонов. - person Some programmer dude; 14.03.2019