Liste des Groupes | Revenir à cl c |
On 05/11/2024 13:29, David Brown wrote: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.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();
}>Your example is an improvement on your previous ones. At least it attempts to deal with out-of-range conditions!
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.
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.)
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.
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.// Take a pointer to an array of two ints, add them, and return the sumThis is a different category of error.
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?).
Here's a related example of what I'd class as a language error: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.
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.
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.
Les messages affichés proviennent d'usenet.