Path: csiph.com!news.mixmin.net!eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c++ Subject: Re: `bool` in pointer arithmetic: when does the promotion occur, if ever? Date: Mon, 15 Aug 2022 14:57:24 -0700 Organization: None to speak of Lines: 76 Message-ID: <87lerpcgqj.fsf@nosuchdomain.example.com> References: <86fshxur3q.fsf@linuxsc.com> MIME-Version: 1.0 Content-Type: text/plain Injection-Info: reader01.eternal-september.org; posting-host="7dee9d38d67e8ab9d211ff6901e0b023"; logging-data="4014165"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19oGu4Gw2Aopa/EVoeIFBs6" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) Cancel-Lock: sha1:U/A0HkcttJ9TziIMmFUcp+5Bojc= sha1:eHl5uMxSWcxguUjZch0i8Km0ExU= Xref: csiph.com comp.lang.c++:85952 Tim Rentsch writes: > Andrey Tarasevich writes: > >> Sound like a silly question (and it might just as well be), but >> nevertheless: >> >> int *a = ; >> bool b = true; >> a + b; >> >> How does the binary `+` work in this case? Its operands are an `int *` >> and a `bool`. `bool` is an integer type, so the requirements are met >> and the expression is valid. Naturally we expect that `bool` to be >> promoted to an integer value of 1, and the rest is clear. >> >> But where does it say in the standard that `bool` should get promoted >> in this context? There is no global rule requiring an unconditional >> promotion, i.e. each operator's specification mandates integral >> promotions individually and explicitly. And I don't see integral >> promotions mentioned anywhere in [expr.add]. >> >> It does mention usual arithmetic conversions (UAC), of course, and UAC >> include integral promotions. But UAC are only applicable when _both_ >> operands have enumeration or arithmetic type. UAC are not applied when >> one operand is a pointer. (The definition of UAC does not accommodate >> for such possibility.) >> >> So, how does pointer+bool addition work then? When does `true` turn >> into 1 here? > > Just a few comments.. > > One, I think you are raising a good point. > > Two, my guess is that this issue reflects an oversight on the part > of the C++ standards committee. At the very least, assuming there > is a provision in the C++ standard the gives this result, the > reasoning needed is obscure and deserves a note. > > Three, an argument could be made (for C++20, n4860) that converting > 'true' or 'false' to 1 or 0 is a consequence of the last sentence > of section 7.3 paragraph 1: > > A standard conversion sequence will be applied to an expression > if necessary to convert it to a required destination type. > > Granted, the reasoning is fraught with ambiguity, and that is never > good. But the 'if necessary' provision gives a lot of latitude. I think this is an oversight in the standard, and one that would be fairly straightforward to correct. The C standard, under "Additive operators", says: If both operands have arithmetic type, the usual arithmetic conversions are performed on them. The corresponding wording in the C++ standard says: The usual arithmetic conversions are performed for operands of arithmetic or enumeration type. The description of the "usual arithmetic conversions" is similar in both standards, and assumes that both operands are of arithmetic type. I can't think of any good reason why the "If both operands have arithmetic type," wording *should* apply in C but not in C++. It *should* say that if one operand is of pointer type, the other operand should undergo the integral promotions (but *not* the usual arithmetic conversions). So if you add a pointer and a bool, the bool should be converted to int (0 or 1). -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips void Void(void) { Void(); } /* The recursive call of the void */