Int32 в эпоху читаемых данных ?! [С] - PullRequest
0 голосов
/ 08 апреля 2019

Хорошо, у меня есть эта функция, которая на самом деле работает, но я не понимаю.

Почему это работает так:

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));  
}

1 Ответ

1 голос
/ 09 апреля 2019

Ваша нерабочая версия пытается присвоить значение числового типа объекту типа 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, нет особых оснований полагать, что присвоение будет недействительным. Что касается качества реализации, неудивительно, что присвоение сохраняет значение (что на практике демонстрирует тот факт, что функция работает).

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