Date: Mon, 24 Mar 2025 19:42:11 -0700 From: Mark Millard <marklmi@yahoo.com> To: Ronald Klop <ronald-lists@klop.ws>, dev-commits-src-main@freebsd.org Subject: Re: git: c18a16ebcf5b - main - kern_proc_kqueues_out(): maxlen == -1 means there is no maxlen Message-ID: <9EAC57CC-CBB6-4039-B7EA-C1D41FADBB52@yahoo.com> References: <9EAC57CC-CBB6-4039-B7EA-C1D41FADBB52.ref@yahoo.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Olivier Certner <olce_at_freebsd.org> wrote on Date: Mon, 24 Mar 2025 15:59:20 UTC " > > (snip)=20 > > > + if (maxlen =3D=3D -1 || maxlen =3D=3D 0) > > As maxlen is of the unsigned type size_t, how can it be -1? > > Or am I mistaken on this? >=20 > It's of course true that 'maxlen' can't be -1 mathematically as it has = an unsigned type, but that's not what 'maxlen =3D=3D -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 '=3D=3D' 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 =3D=3D UINT_MAX' on 32-bit = machines or 'maxlen =3D=3D ULONG_MAX' on 64-bit ones. >=20 > 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 =3D=3D (or !=3D) and avoids any involvement of signed types when maxlen is unsigned: maxlen =3D=3D ~(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 =3D -1; // constraint violation constexpr unsigned int uint_max =3D -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." =3D=3D=3D Mark Millard marklmi at yahoo.com
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9EAC57CC-CBB6-4039-B7EA-C1D41FADBB52>