Your non-working version attempts to assign a value of numeric type to an object of type struct tm
:
struct tm newtime;
newtime = timeH;
No behavior is defined for such assignments, and its not clear what behavior could be expected other than outright rejection of the code. When it does reject that code, surely your compiler emits a diagnostic that explains that it has done so because of incompatible operands of the =
operator.
Your non-working version also attempts to pass an argument of type struct tm
to function asctime()
, which expects instead a pointer to such a structure:
printf("%s\n", asctime(newtime));
Structures and pointers to them are not interchangeable. Your compiler may diagnose this, too, emitting one or more additional error messages about incompatible types.
Now let's consider the working version. I note first that local variable newtime
is declared differently in that version, as a pointer to a struct tm
:
struct tm *newtime;
That takes care of the second issue above. I furthermore note that struct tm *
is also the type returned by the localtime()
function, so the assignment of that function's result to that newtime
is perfectly fine.
From there, we observe that the argument to localtime
must have type time_t *
, which is exactly the type of the expression &long_time
, given that long_time
itself is a time_t
.
So the only remaining point of possible confusion that I see revolves around the assignment of timeH
, an unsigned __int32
, to variable long_time
. Unless some nasty obfuscation is going on, however, unsigned __int32
is an integer type. The standard tells us, furthermore, that time_t
is a "real [type] capable of representing times" (C2011, paragraph 7.27.1/3). In that context, "real" has a meaning based on mathematical usage of that term; overall, it's saying that time_t
is a numeric type with no imaginary component -- i.e. that the values it can represent form a subset of the real numbers.
Exactly what type time_t
is is not specified, but C broadly permits assignments between different numeric types, with few caveats or restrictions. Thus, even though we don't know exactly what type time_t
is, there's no particular reason to suppose that the assignment would be invalid. As a quality of implementation issue, it is not surprising that the assignment is value-preserving (which is demonstrated in practice by the fact that the function works).