Practically speaking yes. In all modern implementations in major OSes time_t is the number of seconds since POSIX epoch, so if time_t is larger than int32_t then it's immune to the y2038 problem
You can also check if __USE_TIME_BITS64 is defined in 32-bit Linux and if _USE_32BIT_TIME_T is not defined in 32-bit Windows to know if it's 2038-safe
However regarding the C++ standard, things aren't as simple. time_t in C++ is defined in <ctime> which has the same content as <time.h> in C standard. And in C time_t isn't defined to have any format
3. The types declared are size_t (described in 7.19);
clock_t
and
time_t
which are real types capable of representing times;
4. The range and precision of times representable in clock_t and time_t are implementation-defined
http://port70.net/~nsz/c/c11/n1570.html#7.27.1p3
So it's permitted for some implementation to have for example double as time_t and store picoseconds from 1/1 year 16383 BCE, or even a 64-bit integer with only 32 value bits and 32 padding bits. That may be one of the reasons difftime() returns a double
To check y2038 issue portably at run time you can use mktime
The mktime function returns the specified calendar time encoded as a value of type time_t. If the calendar time cannot be represented, the function returns the value (time_t)(-1).
http://port70.net/~nsz/c/c11/n1570.html#7.27.2.3p3
struct tm time_str;
time_str.tm_year = 2039 - 1900;
time_str.tm_mon = 1 - 1;
time_str.tm_mday = 1;
time_str.tm_hour = 0;
time_str.tm_min = 0;
time_str.tm_sec = 1;
time_str.tm_isdst = -1;
if (mktime(&time_str) == (time_t)(-1))
std::cout << "Not y2038 safe\n";