Ошибочное выходное значение clock_t на printf

У меня есть следующий код:

#include <stdio.h>
#include <time.h>

clock_t a;

void f(void) {
    a = clock();
    printf("in f(): %g\n", a);
}

void main(void) {
    f();
    printf("in main(): %g\n", a);
}

Скомпилировав его с помощью MinGW gcc и запустив его, вы получите примерно такой вывод:

in f(): -1.#QNAN
in main(): 1.49845e-307

Вопрос. Почему a содержит -1.#QNAN? Хотя я понимаю что это значит, я не вижу, что пошло не так в коде. Сначала я предположил, что это как-то связано со спецификатором формата печати для типа clock_t, но ответы из этот поток stackoverflow говорит об обратном. Даже чтобы убедиться, я быстро покопался в стандартных заголовках и выяснил, что clock_t — это typedef для long (по крайней мере, на моей машине), а это значит, что в отображении значения нет ничего плохого. Может быть, это ошибка в функции clock()?


Редактировать: сразу после прочтения комментариев я понял, что моя реальная проблема заключается в том, что я ожидал, что a будет каким-то сверхмалым значением с плавающей запятой, настолько плохо, что я забыл, что clock_t, как я уже сказал, определен на моя машина типа long. Извините за беспокойство и спасибо всем за ваше время.


person Christian    schedule 13.02.2018    source источник
comment
В ответе на другой вопрос используется %g после преобразования значения в double. Вы, кажется, не делаете этого.   -  person Bo Persson    schedule 13.02.2018
comment
Тип clock_t не указан. Поэтому %g может быть неподходящим оператором формата: en.cppreference.com/w/ cpp/хроно/c/clock_t   -  person Richard Critten    schedule 13.02.2018
comment
clock_t - это целочисленный тип, а не float, поэтому вы не можете использовать формат %g для его печати, проверьте printf(3) документацию на наличие допустимых спецификаторов формата.   -  person Luis Colorado    schedule 14.02.2018


Ответы (2)


Пожалуйста, всегда обращайте внимание на предупреждение вашего компилятора:

warning: format specifies type 'double' but the argument has type
      'clock_t' (aka 'unsigned long') [-Wformat]
    printf("in f(): %g\n", a);
                    ~~     ^
                    %lu

Компилятор даже подскажет, как исправить. Короче говоря, вы не можете указать от double до printf(), когда данные unsigned long.

person llllllllll    schedule 13.02.2018
comment
Извините, это сообщение специфично для CLANG, он может использовать компилятор, который не выдает такого предупреждения. Было бы лучше порекомендовать ему посмотреть документацию printf(3) о том, как печатать целочисленные типы, например clock_t. - person Luis Colorado; 14.02.2018

%g предназначен для печати чисел с плавающей запятой, но вы передали clock_t (который может быть любым арифметическим типом, например, 32-битным целым числом).

Вам нужно привести к double, если вы хотите использовать %g:

printf("in main(): %g\n", static_cast<double>(a));
person Simple    schedule 13.02.2018