The code attempts to determine whether off_t
is at least 64 bits wide, including a sign bit.
In STATIC_ASSERT
, if COND
is true, 1 - 2*!(COND)
evaluates as 1-2*!1
= 1-2*0
= 1
, and the array size is 1, which is fine. If COND
is false, it evaluates as 1-2*!0
= 1-2*1
= -1
, which causes the compiler to issue a diagnostic. So STATIC_ASSERT
acts to generate a compiler message if COND
is false.
LARGE_OFF_T
attempts to perform some arithmetic in the off_t
type. If off_t
is at least 64 bits wide, (off_t) 1 << 31) << 31
evaluates to 262. Then the whole expression evaluates to 262 − 1 + 262 = 263−1. This number has a remainder of 721 modulo 2147483629 and 1 modulo 2147483647, so it passes the test and does not cause the compiler to issue a diagnostic.
If off_t
is, say, 32 bits wide and unsigned, (off_t) 1 << 31) << 31
evaluates to 0, and the whole expression evaluates to 0 − 1 + 0 = 232−1 (since unsigned arithmetic wraps), which has a remainder modulo 2147483629 of 37, so it fails the test, and the compiler generates a diagnostic.
The test is not reliable if off_t
is signed. If off_t
is signed and 32 bits wide, the behavior of (off_t) 1 << 31
is not defined by the C standard. If it is signed and less than 63 bits wide, the behavior of ((off_t) 1 << 31) << 31
is undefined, and, if it is signed and less than 64 bits wide, the final addition is undefined.
If the test is failing for you, you need to correct it by adjusting the build conditions so that off_t
is an integer type that is at least 64 bits wide. There is insufficient information in the question to say how to do this.
There are indications in the code that it expects off_t
to be a signed type. If it were known to be unsigned, then one could ensure it were at least 64 bits simply by testing 18446744073709551615u <= (off_t) -1
. And value that the code attempts to construct, 263−1, is the maximum value of a 64-bit signed integer, rather than an unsigned integer. This is unfortunate because, as indicated above, if off_t
is signed and less than 64 bits wide, the operations have undefined behavior. A better approach might be to test 9223372036854775807 == (off_t) 9223372036854775807
, because overflow during conversion to a signed integer type is at least implementation-defined, rather than not defined by the C standard. One might also settle for 64 <= sizeof(off_t) * CHAR_BIT
. (CHAR_BIT
is defined in <limits.h>
.)