-3

Ok, so, I have this function here that actually DOES work, but i don't get it.

Why does it work like this:

void timeToData(unsigned __int32 timeH)
{
     struct tm *newtime;
     time_t long_time = timeH;
     newtime = localtime(&long_time);
     printf("%s\n", asctime(newtime));  
}

And not like this?

void timeToData(unsigned __int32 timeH)
{
     struct tm newtime;
     newtime = timeH;
     printf("%s\n", asctime(newtime));  
}
almanfu
  • 1
  • 2

1 Answers1

1

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).

John Bollinger
  • 160,171
  • 8
  • 81
  • 157