Deutsch   English   Français   Italiano  
<vgdvfj$1m6ho$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: David Brown <david.brown@hesbynett.no>
Newsgroups: comp.lang.c
Subject: Re: else ladders practice
Date: Tue, 5 Nov 2024 21:33:55 +0100
Organization: A noiseless patient Spider
Lines: 197
Message-ID: <vgdvfj$1m6ho$1@dont-email.me>
References: <3deb64c5b0ee344acd9fbaea1002baf7302c1e8f@i2pn2.org>
 <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>
 <vg3b98$3cc8q$1@dont-email.me> <vg5351$3pada$1@dont-email.me>
 <vg62vg$3uv02$1@dont-email.me> <vgd3ro$2pvl4$1@paganini.bofh.team>
 <vgd6jh$1hmjc$1@dont-email.me> <vgds97$2r682$1@paganini.bofh.team>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Tue, 05 Nov 2024 21:33:56 +0100 (CET)
Injection-Info: dont-email.me; posting-host="98687be8651188f57cf251c574270178";
	logging-data="1776184"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX18uaIZu+OTfJjSFtqxrxaZZWBt6LUSQgZk="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:lkqMcujCXg0FDQFzuilLoV2+On8=
In-Reply-To: <vgds97$2r682$1@paganini.bofh.team>
Content-Language: en-GB
Bytes: 10030

On 05/11/2024 20:39, Waldek Hebisch wrote:
> David Brown <david.brown@hesbynett.no> wrote:
>> On 05/11/2024 13:42, Waldek Hebisch wrote:
>>> Bart <bc@freeuk.com> wrote:
>>>>
>>>> Then we disagree on what 'multi-way' select might mean. I think it means
>>>> branching, even if notionally, on one-of-N possible code paths.
>>>
>>> OK.
>>
>> I appreciate this is what Bart means by that phrase, but I don't agree
>> with it.  I'm not sure if that is covered by "OK" or not!
> 
> You may prefer your own definition, but Bart's is resonable one.

The only argument I can make here is that I have not seen "multi-way 
select" as a defined phrase with a particular established meaning.  So 
it simply means what the constituent words mean - selecting something 
from multiple choices.  There are no words in that phrase that talk 
about "branching", or imply a specific order to events.  It is a very 
general and vague phrase, and I cannot see a reason to assume it has 
such a specific meaning as Bart wants to assign to it.  And as I have 
pointed out in other posts, there are constructs in many languages 
(including C) that fit the idea of a selection from one of many things, 
but which do not fit Bart's specific interpretation of the phrase.

Bart's interpretation is "reasonable" in the sense of being definable 
and consistent, or at least close enough to that to be useable in a 
discussion.  But neither he, I, or anyone else gets to simply pick a 
meaning for such a phrase and claim it is /the/ definition.  Write a 
popular and influential book with this as a key phrase, and /then/ you 
can start calling your personal definition "the correct" definition.

>   
>>>    
>>>> The whole construct may or may not return a value. If it does, then one
>>>> of the N paths must be a default path.
>>>
>>>
>>> You need to cover all input values.  This is possible when there
>>> is reasonably small number of possibilities.  For example, switch on
>>> char variable which covers all possible values does not need default
>>> path.  Default is needed only when number of possibilities is too
>>> large to explicitely give all of them.  And some languages allow
>>> ranges, so that you may be able to cover all values with small
>>> number of ranges.
>>>
>>
>> I think this is all very dependent on what you mean by "all input values".
>>
>> Supposing I declare this function:
>>
>> // Return the integer square root of numbers between 0 and 10
>> int small_int_sqrt(int x);
>>
>>
>> To me, the range of "all input values" is integers from 0 to 10.  I
>> could implement it as :
>>
>> int small_int_sqrt(int x) {
>>         if (x == 0) return 0;
>>         if (x < 4) return 1;
>>         if (x < 9) return 2;
>>         if (x < 16) return 3;
>>         unreachable();
>> }
>>
>> If the user asks for small_int_sqrt(-10) or small_int_sqrt(20), that's
>> /their/ fault and /their/ problem.  I said nothing about what would
>> happen in those cases.
>>
>> But some people seem to feel that "all input values" means every
>> possible value of the input types, and thus that a function like this
>> should return a value even when there is no correct value in and no
>> correct value out.
> 
> Well, some languages treat types more seriously than C.  In Pascal
> type of your input would be 0..10 and all input values would be
> handled.  Sure, when domain is too complicated to express in type
> than it could be documented restriction.  Still, it makes sense to
> signal error if value goes outside handled rage, so in a sense all
> values of input type are handled: either you get valid answer or
> clear error.

No, it does not make sense to do that.  Just because the C language does 
not currently (maybe once C++ gets contracts, C will copy them) have a 
way to specify input sets other than by types, does not mean that 
functions in C always have a domain matching all possible combinations 
of bits in the underlying representation of the parameter's types.

It might be a useful fault-finding aid temporarily to add error messages 
for inputs that are invalid but can physically be squeezed into the 
parameters.  That won't stop people making incorrect declarations of the 
function and passing completely different parameter types to it, or 
finding other ways to break the requirements of the function.

And in general there is no way to check the validity of the inputs - you 
usually have no choice but to trust the caller.  It's only in simple 
cases, like the example above, that it would be feasible at all.


There are, of course, situations where the person calling the function 
is likely to be incompetent, malicious, or both, and where there can be 
serious consequences for what you might prefer to consider as invalid 
input values.  You have that for things like OS system calls - it's no 
different than dealing with user inputs or data from external sources. 
But you handle that by extending the function - increase the range of 
valid inputs and appropriate outputs.  You no longer have a function 
that takes a number between 0 and 10 and returns the integer square root 
- you now have a function that takes a number between -(2 ^ 31 + 1) and 
(2 ^ 31) and returns the integer square root if the input is in the 
range 0 to 10 or halts the program with an error message for other 
inputs in the wider range.  It's a different function, with a wider set 
of inputs - and again, it is specified to give particular results for 
particular inputs.


> 
>> This is, IMHO, just nonsense and misunderstands the contract between
>> function writers and function users.
>>
>> Further, I am confident that these people are quite happen to write code
>> like :
>>
>> // Take a pointer to an array of two ints, add them, and return the sum
>> int sum_two_ints(const int * p) {
>>         return p[0] + p[1];
>> }
> 
> I do not think that people wanting strong type checking are happy
> with C.  Simply, either they use different language or use C
> without bitching, but aware of its limitations.  

Sure.  C doesn't give as much help to writing correct programs as some 
other languages.  That doesn't mean the programmer can't do the right thing.

> I certainly would
> be quite unhappy with code above.  It is possible that I would still
> use it as a compromise (say if it was desirable to have single
> prototype but handle points in spaces of various dimensions),
> but my first attempt would be something like:
> 
> typedef struct {int p[2];} two_int;
> ....
> 

I think you'd quickly find that limiting and awkward in C (but it might 
be appropriate in other languages).  But don't misunderstand me - I am 
all in favour of finding ways in code that make input requirements 
clearer or enforceable within the language - never put anything in 
comments if you can do it in code.  You could reasonably do this in C 
for the first example :


// Do not use this directly
extern int small_int_sqrt_implementation(int x);


// Return the integer square root of numbers between 0 and 10
static inline int small_int_sqrt(int x) {
	assert(x >= 0 && x <= 10);
	return small_int_sqrt_implementation(x);
}


There is no way to check the validity of pointers in C, but you might at 
least be able to use implementation-specific extensions to declare the 
function with the requirement that the pointer not be null.


>> Perhaps, in a mistaken belief that it makes the code "safe", they will add :
========== REMAINDER OF ARTICLE TRUNCATED ==========