Re: else ladders practice

Liste des GroupesRevenir à cl c  
Sujet : Re: else ladders practice
De : david.brown (at) *nospam* hesbynett.no (David Brown)
Groupes : comp.lang.c
Date : 06. Nov 2024, 15:50:21
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <vgfvne$25kug$1@dont-email.me>
References : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
User-Agent : Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0
On 05/11/2024 23:48, Bart wrote:
On 05/11/2024 13:29, David Brown wrote:
On 05/11/2024 13:42, Waldek Hebisch wrote:
 
>
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.
 Your example is an improvement on your previous ones. At least it attempts to deal with out-of-range conditions!
No, it does not.  The fact that some invalid inputs also give deterministic results is a coincidence of the implementation, not an indication that the function is specified for those additional inputs or that it does any checking.  I intentionally structured the example this way to show this - sometimes undefined behaviour gives you results you might like, but it is still undefined behaviour.  This function has no defined behaviour for inputs outside the range 0 to 10, because I gave no definition of its behaviour - the effect of particular implementations of the function is irrelevant to that.
As I suspected it might, this apparently confused you.

 However there is still the question of providing that return type. If 'unreachable' is not a special language feature, then this can fail either if the language requires the 'return' keyword, or 'unreachable' doesn't yield a compatible type (even if it never returns because it's an error handler).
"unreachable()" is a C23 standardisation of a feature found in most high-end compilers.  For gcc and clang, there is __builtin_unreachable(), and MSVC has its version.  The functions are handled by the compilers as "undefined behaviour".  (I mean that quite literally - gcc and clang turn it into an "UB" instruction in their internal representations.)
Clearly, "unreachable()" has no return type - it does not in any sense "return".  And since the compiler knows it will never be "executed", it knows control will never fall off the end of that function.  You don't need a type for something that can never happen (it's like if I say "this is a length of 0" and you ask "was that 0 metres, or 0 inches?" - the question is meaningless).

 Getting that right will satisfy both the language (if it cared more about such matters than C apparently does), and the casual reader curious about how the function contract is met (that is, supplying that promised return int type if or when it returns).
C gets it right here.  There is no need for a return type when there is no return - indeed, trying to force some sort of type or "default" value would be counterproductive.  It would be confusing to the reader, add untestable and unexecutable source code, make code flow more complicated, break invariants, cripple correctness analysis of the rest of the code, and make the generated object code inefficient.
Remember how the function is specified.  All you have to do is use it correctly - go outside the specifications, and I make no promises or guarantees about what will happen.  If you step outside /your/ side of the bargain by giving it an input outside 0 to 10, then I give you no more guarantees that it will return an int of any sort than I give you a guarantee that it would be a great sales gimmick if printed on a t-shirt.
But what I /can/ give you is something that can be very useful in being sure the rest of your code is correct, and which is impossible for a function with "default" values or other such irrelevant parts.  I can guarantee you that:
int y = small_int_sqrt(x);
assert(y * y <= x);
assert ((y + 1) * (y + 1) > x);
That is to say - I can guarantee that the function works and gives you the correct results.
But supposing I had replaced the "unreachable();" with a return of a default value - let's say 42, since that's the right answer even if you don't know the question.  What does the user of small_int_sqrt() know now?
Now you know that "y" is an int.  You have no idea if it is a correct or useful result, unless you have first checked that x is in the specified range of 0 to 10.
If you /have/ checked (in some way) that x is valid, then why would you bother calling the function when x is invalid?  And thus why would you care what the function does or does not do when x is invalid?
And if you haven't checked that x is valid, why would you bother calling the function if you have no idea whether or not it results in something useful and correct?
So we have now established that returning a default int value is worse than useless - there are no circumstances in which it can be helpful, and it ruins the guarantees you want in order to be sure that the calling code is correct.
Let's now look at another alternative - have the function check for validity, and return some kind of error signal if the input is invalid. There are two ways to do this - we can have a value of the main return type acting as an error signal, or we can have an additional return value.
If we pick the first one - say, return -1 on error - then we have a compact solution that is easy to check for the calling function.  But now we have a check for validity of the input whether we need it or not (since the callee function does the checking, even if the caller function knows the values are valid), and the caller function has to add a check a check for error return values.  The return may still be an "int", but it is no longer representative of an integer value - it multiplexes two different concepts.  We have lost the critical correctness equations that we previously had.  And it won't work at all if there is no choice of an error indicator.
If we pick the second one, we need to return two values.  The checking is all the same, but at least the concepts of validity and value are separated.  Now we have either a struct return with its added efficiency costs, or a monstrosity from the dark ages where the function must take a pointer parameter for where to store the results.  (And how is the function going to check the validity of that pointer?  Or is it somehow okay to skip that check while insisting that a check of the other input is vital?)  This has most of the disadvantages of the first choice, plus extra efficiency costs.
All in all, we have a significant costs in various aspects, with no real benefit, all in the name of a mistaken belief that we are avoiding undefined behaviour.

 
// 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];
}
>
Perhaps, in a mistaken belief that it makes the code "safe", they will add :
>
     if (!p) return 0;
>
at the start of the function.  But they will not check that "p" actually points to an array of two ints (how could they?), nor will they check for integer overflow (and what would they do if it happened?).
 This is a different category of error.
 
No, it is not.  It is just another case of a function having preconditions on the input, and whether or not the called function should check those preconditions.  You can say you think it is vital for functions to do these checks itself, or you can accept that it is the responsibility of the calling code to provide valid inputs.  But you don't get to say it is vital to check /some/ types of inputs, but other types are fine to take on trust.

Here's a related example of what I'd class as a language error:
     int a;
    a = (exit(0), &a);
 A type mismatch error is usually reported. However, the assignment is never done because it never returns from that exit() call.
 I expect you wouldn't think much of a compiler that didn't report such an error because that code is never executed.
I would expect the compiler to know that "exit()" can't return, so the value of "a" is never used and it can be optimised away.  But I do also expect that the compiler will enforce the rules of the language - syntax and grammar rules, along with constraints and anything else it is able to check.  And even if I said it was reasonable for a language to say this "assignment" is not an error since it can't be executed, I think trying to put that level of detail into a language definition (and corresponding compilers) would quickly be a major complexity for no real-world gain.

 But to me that is little different from running into the end of function without the proper provisions for a valid return value.
 
Yes, I think so too.

Date Sujet#  Auteur
31 Oct 24 * else ladders practice255fir
31 Oct 24 +* Re: else ladders practice9Anton Shepelev
31 Oct 24 i+- Re: else ladders practice1fir
31 Oct 24 i`* Re: else ladders practice7James Kuyper
1 Nov 24 i `* Re: else ladders practice6David Brown
2 Nov 24 i  +* Re: else ladders practice2James Kuyper
2 Nov 24 i  i`- Re: else ladders practice1David Brown
2 Nov 24 i  `* Re: else ladders practice3fir
2 Nov 24 i   +- Re: else ladders practice1David Brown
2 Nov 24 i   `- Re: else ladders practice1James Kuyper
31 Oct 24 +* Re: else ladders practice5Richard Harnden
31 Oct 24 i+* Re: else ladders practice3fir
31 Oct 24 ii`* Re: else ladders practice2fir
31 Oct 24 ii `- Re: else ladders practice1fir
31 Oct 24 i`- Re: else ladders practice1Bonita Montero
31 Oct 24 +* Re: else ladders practice22Dan Purgert
31 Oct 24 i+* Re: else ladders practice3fir
31 Oct 24 ii`* Re: else ladders practice2Dan Purgert
31 Oct 24 ii `- Re: else ladders practice1fir
16 Nov 24 i`* Re: else ladders practice18Stefan Ram
16 Nov 24 i +* Re: else ladders practice5Bart
16 Nov 24 i i`* Re: else ladders practice4David Brown
19 Nov 24 i i `* Re: else ladders practice3Janis Papanagnou
19 Nov 24 i i  +- Re: else ladders practice1David Brown
19 Nov 24 i i  `- Re: else ladders practice1Michael S
16 Nov 24 i +* Re: else ladders practice3James Kuyper
19 Nov 24 i i`* Re: else ladders practice2Janis Papanagnou
1 Dec 24 i i `- Re: else ladders practice1Tim Rentsch
16 Nov 24 i +* Re: else ladders practice2Lew Pitcher
17 Nov 24 i i`- Re: else ladders practice1Tim Rentsch
20 Nov 24 i +* Re: else ladders practice3Dan Purgert
30 Nov 24 i i`* Re: else ladders practice2Rosario19
5 Dec 24 i i `- Re: else ladders practice1Dan Purgert
1 Dec 24 i `* Re: else ladders practice4Waldek Hebisch
1 Dec 24 i  `* Re: else ladders practice3Janis Papanagnou
2 Dec 24 i   `* Re: else ladders practice2Waldek Hebisch
2 Dec 24 i    `- Re: else ladders practice1Janis Papanagnou
31 Oct 24 +- Re: else ladders practice1Janis Papanagnou
31 Oct 24 `* Re: else ladders practice217Bart
1 Nov 24  `* Re: else ladders practice216fir
1 Nov 24   +* Re: else ladders practice198Bart
1 Nov 24   i+* Re: else ladders practice196fir
1 Nov 24   ii`* Re: else ladders practice195Bart
1 Nov 24   ii `* Re: else ladders practice194fir
1 Nov 24   ii  `* Re: else ladders practice193fir
1 Nov 24   ii   `* Re: else ladders practice192Bart
1 Nov 24   ii    `* Re: else ladders practice191David Brown
1 Nov 24   ii     `* Re: else ladders practice190Bart
1 Nov 24   ii      `* Re: else ladders practice189David Brown
1 Nov 24   ii       `* Re: else ladders practice188Bart
2 Nov 24   ii        `* Re: else ladders practice187David Brown
2 Nov 24   ii         `* Re: else ladders practice186Bart
3 Nov 24   ii          +- Re: else ladders practice1Tim Rentsch
3 Nov 24   ii          +* Re: else ladders practice4fir
3 Nov 24   ii          i`* Re: else ladders practice3Bart
3 Nov 24   ii          i `* Re: else ladders practice2fir
3 Nov 24   ii          i  `- Re: else ladders practice1fir
3 Nov 24   ii          +* Re: else ladders practice4fir
3 Nov 24   ii          i`* Re: else ladders practice3Bart
3 Nov 24   ii          i `* Re: else ladders practice2fir
3 Nov 24   ii          i  `- Re: else ladders practice1fir
3 Nov 24   ii          +* Re: else ladders practice35David Brown
3 Nov 24   ii          i+- Re: else ladders practice1Kaz Kylheku
3 Nov 24   ii          i+* Re: else ladders practice23Bart
4 Nov 24   ii          ii+* Re: else ladders practice21David Brown
4 Nov 24   ii          iii`* Re: else ladders practice20Bart
4 Nov 24   ii          iii +* Re: else ladders practice2David Brown
5 Nov 24   ii          iii i`- Re: else ladders practice1Bart
5 Nov 24   ii          iii `* Re: else ladders practice17David Brown
5 Nov 24   ii          iii  +* Re: else ladders practice2Bart
5 Nov 24   ii          iii  i`- Re: else ladders practice1David Brown
6 Nov 24   ii          iii  +* Re: else ladders practice5Bart
6 Nov 24   ii          iii  i`* Re: else ladders practice4David Brown
6 Nov 24   ii          iii  i `* Re: else ladders practice3Bart
7 Nov 24   ii          iii  i  `* Re: else ladders practice2David Brown
7 Nov 24   ii          iii  i   `- Re: else ladders practice1Bart
9 Nov 24   ii          iii  `* Re: else ladders practice9Janis Papanagnou
9 Nov 24   ii          iii   `* Re: else ladders practice8David Brown
10 Nov 24   ii          iii    `* Re: else ladders practice7Janis Papanagnou
10 Nov 24   ii          iii     `* Re: else ladders practice6David Brown
19 Nov 24   ii          iii      `* Re: else ladders practice5Janis Papanagnou
19 Nov 24   ii          iii       `* Re: else ladders practice4David Brown
19 Nov 24   ii          iii        `* Re: else ladders practice3Janis Papanagnou
19 Nov 24   ii          iii         `* Re: else ladders practice2David Brown
20 Nov 24   ii          iii          `- Re: else ladders practice1Janis Papanagnou
9 Nov 24   ii          ii`- Re: else ladders practice1Janis Papanagnou
8 Nov 24   ii          i+* Re: else ladders practice9Janis Papanagnou
8 Nov 24   ii          ii+* Re: else ladders practice4David Brown
9 Nov 24   ii          iii`* Re: else ladders practice3Janis Papanagnou
9 Nov 24   ii          iii `* Re: else ladders practice2David Brown
10 Nov 24   ii          iii  `- Re: else ladders practice1Janis Papanagnou
9 Nov 24   ii          ii`* Re: else ladders practice4Bart
9 Nov 24   ii          ii `* Re: else ladders practice3Janis Papanagnou
9 Nov 24   ii          ii  `* Re: else ladders practice2Bart
10 Nov 24   ii          ii   `- Re: else ladders practice1Janis Papanagnou
8 Nov 24   ii          i`- Re: else ladders practice1Bart
5 Nov 24   ii          `* Re: else ladders practice141Waldek Hebisch
5 Nov 24   ii           +- Re: else ladders practice1fir
5 Nov 24   ii           +* Re: else ladders practice24David Brown
5 Nov 24   ii           i+* Re: else ladders practice17Waldek Hebisch
5 Nov 24   ii           ii`* Re: else ladders practice16David Brown
6 Nov 24   ii           i`* Re: else ladders practice6Bart
5 Nov 24   ii           `* Re: else ladders practice115Bart
1 Nov 24   i`- Re: else ladders practice1fir
2 Nov 24   `* Re: else ladders practice17Tim Rentsch

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal