I am trying to print time_t without casting it as long int in Microsoft Visual Studio Project and it is giving me unexpected result. The source code is
#include <time.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <string.h>
int main()
{
int a=1,b=2;
long int c=3;
time_t myTime;
time(&myTime);
printf("%d_%ld_%d_%ld",a,myTime,b,c);
printf("\n");
getchar();
return 0;
}
The output is 1_1389610399_0_2
. This is running fine on my linux machine though.I understand that time_t should not be printed like this but I am not sure why? Please tell me how to debug such problem?
EDIT: I was expecting the output to be 1_1389610399_2_3
given the fact that time_t
is considered as arithmetic in C.
Who says time_t
is a long
? It may be any arithmetic type.
You must explicitly cast it to some defined type when using
printf
.
Use ostream
, and avoid such problems.
I was expecting the output to be
1_1389610399_2_3
You are wrong to expect this. Different types have different sizes, and when you pass the "wrong" type via varargs this means that the receiver can no longer find everything on the stack in the expected locations. That's why behavior is undefined when the formatting codes don't match the arguments: the receiver is not reading the same types that the caller is writing.
The 0
that you see printed out where you expected b
, is the most significant 32 bits of the 64-bit long long
value that is placed on the stack when you pass a time_t
via varargs (in this implementation). The %ld
formatting code only took the first 4 bytes of the value of myTime
, leaving the rest to be taken by the next formatting code.
When it works on linux, that's because time_t
is long
on that implementation and so your format code matches the type you pass.
There is a kind of "all-purpose" way to print any signed integer, which is to convert it to intmax_t
and use the formatting code %j
. Unfortunately you aren't guaranteed that time_t
is a signed type, or even that it's an integer type. So this would be more portable but still not strictly so, because the value of myTime
in theory might not be in range of intmax_t
at all. In C++ you should use std::cout << myTime;
, because that avoids you needing to know the actual type aliased by time_t
(just as long as it's not any kind of char
).
Alternatively you can use difftime
to coerce your time to double
, which you know how to print. Or you can use gmtime
or localtime
to get a broken-down calendar time, each component of which you know how to print either with printf
or with strftime
.
To show its (time_t
) contents in a safe manner, you should first use (ie.) gmtime
to convert it to struct tm
, and then use one of its fields or use strftime
to convert it further to string.
In order to print a 64 bit integer using a format string you have to use %I64d
rather than %ld
.
However, be ware because the type of time_t
depends on your hardware's bitness.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With