Re: git: c18a16ebcf5b - main - kern_proc_kqueues_out(): maxlen == -1 means there is no maxlen
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 25 Mar 2025 02:42:11 UTC
Olivier Certner <olce_at_freebsd.org> wrote on Date: Mon, 24 Mar 2025 15:59:20 UTC " > > (snip) > > > + if (maxlen == -1 || maxlen == 0) > > As maxlen is of the unsigned type size_t, how can it be -1? > > Or am I mistaken on this? > > It's of course true that 'maxlen' can't be -1 mathematically as it has an unsigned type, but that's not what 'maxlen == -1' tests. In this example, 'maxlen' is an unsigned type of size at least equal to 'unsigned int', whose values cannot all be represented in a signed 'int' (well, that last part is true but not the real reason, which has to do with integer ranks). According to the standard promotion rules, and because -1 as an integer constant is interpreted as of type 'int', both arguments of '==' will be converted to 'unsigned int', and conversion of a signed type to an unsigned one is done by computing its congruence to the number of values the latter can represent (this is the mathematical description; with two-complement representation, that's basically just truncating the bits that are "too high", or sign-extending if the unsigned type destination is wider, and in this precise case, just keeping the same exact representation bits). So, basically, this test is equivalent to 'maxlen == UINT_MAX' on 32-bit machines or 'maxlen == ULONG_MAX' on 64-bit ones. > > Relevant C standard passages are, in section Language > Conversions > Arithmetic operands, the "Boolean, characters, and integers", "Signed and unsigned integers" and "Usual arithmetic conversions" chapters, and, under Language > Expressions, the chapter about equality operators (in particular, the fact that it states that the usual arithmetic conversions apply), and chapter Language > Lexical elements > Constants > Integer constants. (This does not invalidate the above material.) Another, longer C23 notation that avoids implicit "usual arithmetic conversions" for == (or !=) and avoids any involvement of signed types when maxlen is unsigned: maxlen == ~(typeof(maxlen))0u It also has the property of the notation surviving various type changes to maxlen that are still unsigned, without needing editing. These days (C23) there are parts of the language for which implicit conversions are not involved: QUOTE (from N3220): The constraints for constexpr objects are intended to enforce checks for portability at translation time. constexpr unsigned int minusOne = -1; // constraint violation constexpr unsigned int uint_max = -1U; // ok . . . END QUOTE Also: "An object declared with the constexpr specifier stores the exact value of its initializer, no implicit value change is applied." === Mark Millard marklmi at yahoo.com