Итак, у меня есть эта функция, которая на самом деле работает, но я ее не понимаю.
Почему это работает так:
void timeToData(unsigned __int32 timeH)
{
struct tm *newtime;
time_t long_time = timeH;
newtime = localtime(&long_time);
printf("%s\n", asctime(newtime));
}
А не так?
void timeToData(unsigned __int32 timeH)
{
struct tm newtime;
newtime = timeH;
printf("%s\n", asctime(newtime));
}
Что вас смущает или удивляет в этой функции?
Все, что вам нужно знать, можно найти здесь: linux.die.net/man/3/местное время
Ваша нерабочая версия пытается присвоить значение числового типа объекту типа struct tm
:
struct tm newtime;
newtime = timeH;
Для таких назначений не определено поведение, и неясно, какое поведение можно ожидать, кроме прямого отказа от кода. Когда он отклоняет этот код, ваш компилятор наверняка выдает диагностику, которая объясняет, что он сделал это из-за несовместимых операндов оператора =
.
Ваша нерабочая версия также пытается передать аргумент типа struct tm
в функцию asctime()
, которая вместо этого ожидает указатель для такой структуры:
printf("%s\n", asctime(newtime));
Структуры и указатели на них не взаимозаменяемы. Ваш компилятор также может диагностировать это, выдавая одно или несколько дополнительных сообщений об ошибках о несовместимых типах.
Теперь рассмотрим рабочий вариант. Прежде всего отмечу, что локальная переменная newtime
в этой версии объявлена по-другому, как указатель для struct tm
:
struct tm *newtime;
Это решает вторую проблему выше. Кроме того, я отмечаю, что struct tm *
также является типом, возвращаемым функцией localtime()
, поэтому присвоение результата этой функции этому newtime
совершенно нормально.
Отсюда мы видим, что аргумент localtime
должен иметь тип time_t *
, который точно совпадает с типом выражения &long_time
, учитывая, что long_time
само по себе является time_t
.
Таким образом, единственная оставшаяся точка возможной путаницы, которую я вижу, связана с присвоением timeH
, unsigned __int32
, переменной long_time
. Однако, если не происходит какое-то неприятное запутывание, unsigned __int32
— это целочисленный тип. Более того, стандарт говорит нам, что time_t
— это «настоящий [тип], способный представлять время» (C2011, пункт 7.27.1/3). В этом контексте «реальный» имеет значение, основанное на математическом использовании этого термина; в целом, это говорит о том, что time_t
— это тип числовой без мнимой составляющей — то есть, что значения, которые он может представлять, образуют подмножество действительных чисел.
Какой именно тип time_t
не указан, но C широко разрешает присваивания между различными числовыми типами с некоторыми оговорками или ограничениями. Таким образом, даже если мы точно не знаем, что такое тип time_t
, нет особых причин предполагать, что присвоение будет недопустимым. Что касается качества реализации, то неудивительно, что присвоение сохраняет значение (что на практике демонстрируется тем фактом, что функция работает).
См. соответствующий вопрос stackoverflow.com/questions/9076494/…, который может быть полезен в этом случае.