This related question is about determining the max value of a signed type at compile-time:
C question: off_t (and other signed integer types) minimum and maximum values
However, I’ve since realized that determining the max value of a signed type (e.g. time_t or off_t) at runtime seems to be a very difficult task.
The closest thing to a solution I can think of is:
uintmax_t x = (uintmax_t)1<<CHAR_BIT*sizeof(type)-2;
while ((type)x<=0) x>>=1;
This avoids any looping as long as type has no padding bits, but if type does have padding bits, the cast invokes implementation-defined behavior, which could be a signal or a nonsensical implementation-defined conversion (e.g. stripping the sign bit).
I’m beginning to think the problem is unsolvable, which is a bit unsettling and would be a defect in the C standard, in my opinion. Any ideas for proving me wrong?
Update: Thankfully, my previous answer below was wrong, and there seems to be a solution to this question.
This program either yields
xcontaining the max possible value of typeT, or generates an implementation-defined signal.Working around the signal case may be possible but difficult and computationally infeasible (as in having to install a signal handler for every possible signal number), so I don’t think this answer is fully satisfactory. POSIX signal semantics may give enough additional properties to make it feasible; I’m not sure.
The interesting part, especially if you’re comfortable assuming you’re not on an implementation that will generate a signal, is what happens when
(T)xresults in an implementation-defined conversion. The trick of the above loop is that it does not rely at all on the implementation’s choice of value for the conversion. All it relies upon is that(T)x==xis possible if and only ifxfits in typeT, since otherwise the value ofxis outside the range of possible values of any expression of typeT.Old idea, wrong because it does not account for the above
(T)x==xproperty:I think I have a sketch of a proof that what I’m looking for is impossible:
INT_MAX>32767.INT_MAXandINT_MINare each divided by 2.The essential idea of this outline is that, due to the fact that everything related to out-of-bound values with signed types is implementation-defined or undefined behavior, an arbitrary number of the high value bits of a signed integer type can be considered as padding bits without actually making any changes to the implementation except the limit macros in
limits.h.Any thoughts on if this sounds correct or bogus? If it’s correct, I’d be happy to award the bounty to whoever can do the best job of making it more rigorous.