The constant SIZE_MAX non-negative and has type size_t . For brevity, I will define:
#define S SIZE_MAX
The mathematical value of S+1 is, or may be, as you indicated, out of range for any integer type.
I will write S1 for the mathematical value of S+1 .
If we consider the logarithm (in base 2, if you want) of S1 , then we have:
logarithm(sqrt(S1)) == (1.0/2.0) logarithm(S1)
On the other hand, in almost any real situation, we will have that S is represented as a binary number having only bits 1 . The number b this bit, in the general case, is the number CHAR_BIT times the power of two times CHAR_BIT: 16, 32, 64, 128 ... We denote the index of this power by p . So for CHAR_BIT == 8 we have:
16 == CHAR_BIT * 2 ----> p == 1 32 == CHAR_BIT * 4 ----> p == 2 64 == CHAR_BIT * 8 ----> p == 3
Now we have:
logarithm(S1) == b == CHAR_BIT * (2 ** p) (I am denoting with ** to the "power math. operator"). logarithm(sqrt(S1)) == logaritm(S1) / 2.0 == CHAR_BIT * (2 ** p) / 2.0 == CHAR_BIT * (2 ** (p - 1))
Assuming or knowing that each bit in size_t used only to represent bits of an integer, we have this equality with some (unknown) p value:
sizeof(size_t) == b == CHAR_BIT * (2 ** p)
We can assume that , for the current state in 2014, that the value p <= 5 , let's say (you can increase this magic number 5 to higher values โโin the future),
Now consider the following expression, designed to "search and find" the value of b under the assumption that p <= 5 :
#define S_1 ((size_t)1ULL) #define b (sizeof(size_t)) #define bitexpr(p) ((size_t)(CHAR_BIT * (S_1 << (p)))) #define expr(p) ((size_t) (S_1 << (p))) #define exp2_expr_1(p) ((size_t)(S_1 << bitexpr(p-1)))
The SRSM macro actually brings the square root of S+1 , but I suppose you can figure out what to do with this number.
The important thing is that the square root of SIZE_MAX can be obtained using purely integer constant expressions .
If you want, the "magic" number 5 can be changed by another.
A more general approach, designed to solve an arbitrary situation, on any possible machine that meets the standard, would be more complex. The method used in this message is independent of the value having CHAR_BIT , but it uses the number of bytes to be a value of 2.
EDITED: I changed the โsearchโ method a bit, starting from 1, and then growing to avoid possible โfalseโ matches with the << operator and large numbers (no one ever knows ...). Now, the first match is probably correct.