Deutsch English Français Italiano |
<vg3b98$3cc8q$1@dont-email.me> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!eternal-september.org!feeder2.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Bart <bc@freeuk.com> Newsgroups: comp.lang.c Subject: Re: else ladders practice Date: Fri, 1 Nov 2024 19:47:53 +0000 Organization: A noiseless patient Spider Lines: 84 Message-ID: <vg3b98$3cc8q$1@dont-email.me> References: <3deb64c5b0ee344acd9fbaea1002baf7302c1e8f@i2pn2.org> <vg0t3j$2ruor$1@dont-email.me> <78eabb4054783e30968ae5ffafd6b4ff2e5a5f17@i2pn2.org> <vg2g37$37mh3$1@dont-email.me> <6724CFD2.4030607@grunge.pl> <vg2llt$38ons$1@dont-email.me> <2491a699388b5891a49ef960e1ad8bb689fdc2ed@i2pn2.org> <b681ee05856e165c26a5c29bf42a8d9d53843d6d@i2pn2.org> <vg2ttn$3a4lk$1@dont-email.me> <vg33gs$3b8n5$1@dont-email.me> <vg358c$3bk7t$1@dont-email.me> <vg37nr$3bo0c$1@dont-email.me> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Fri, 01 Nov 2024 20:47:52 +0100 (CET) Injection-Info: dont-email.me; posting-host="043844d4a216b291756c29a01a715cc9"; logging-data="3551514"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+LRbTzXPZqx9yvf7F5Ktpp" User-Agent: Mozilla Thunderbird Cancel-Lock: sha1:MsqTo3Sy8U/DHlm7VfMn/OGausI= Content-Language: en-GB In-Reply-To: <vg37nr$3bo0c$1@dont-email.me> Bytes: 4496 On 01/11/2024 18:47, David Brown wrote: > On 01/11/2024 19:05, Bart wrote: >> On 01/11/2024 17:35, David Brown wrote: >>> >>> What you have written here is all correct, but a more common method >>> would be to avoid having three printf's : >>> >>> void shout_a_number(int n) { >>> printf( (const char* []) { "ONE", "TWO", "THREE" } [n] ); >>> } >>> >>> That's more likely to match what people would want. >> >> I was also trying to show that all elements are evaluated, so each has >> to have some side-effect to illustrate that. > > Fair enough. > >> >> A true N-way-select construct (C only really has ?:) would evaluate >> only one, and would deal with an out-of-range condition. > > That's a matter of opinion and design choice, rather than being > requirements for a "true" select construct. I don't think it's just opinion. In general, an if-else-if chain (which was the point of the OP), would evaluate only one branch. So would a switch-case construct if sensibly implemented (in C's version, anything goes). The same applies to C's c?a:b operator: only one of a or b is evaluated, not both. (This also why implementing if, switch, ?: via functions, which lots are keen to do in the reddit PL forum, requires closures, lazy evaluation or other advanced features.) > You are free to choose the > rules you want for your own language, but you are not free to dictate > what you think the rules should be for others. (You are welcome to > /opinions/, of course.) > >> >> (In my implementations, a default/else branch value must be provided >> if the whole thing is expected to return a value.) >> > > OK, if that's what you want. My preference, if I were putting together > what /I/ thought was an idea language for /my/ use, would be heavy use > of explicit specifications and contracts for code, so that a > default/else branch is either disallowed (if there the selection covers > all legal values) or required (if the selection is abbreviated). A > default value "just in case" is, IMHO, worse than useless. All such multiway constructs in my languages (there are 4, one of which the job of both 'if' and C's ?:) have an optional else branch. A missing 'else' has an notional 'void' type. But it becomes mandatory if the whole thing returns a value, to satisfy the type system, because otherwise it will try and match with 'void'. SOMETHING needs to happen when none of the branches are executed; what value would be returned then? The behaviour needs to be defined. You don't want to rely on compiler analysis for this stuff. In C on the other hand, the ':' of '?:' is always needed, even when it is not expected to yield a value. Hence you often see this things like this: p == NULL ? puts("error"): 0; Here, gcc at least, also requires the types of the two branches to match, even though the whole construct yields no common value. Meanwhile I allow this (if I was keen on a compact form): (p = nil | print "error") No else is needed.