On 2023-07-21, Jakob Bohm <
[email protected]d> wrote:
On 2023-07-20 19:17, Tim Rentsch wrote:
Kaz Kylheku <[email protected]> writes:
I've noticed that both arguments of fopen are restrict-qualified.
What I think you mean is that the arguments given in the prototype
declaration in the C standard are qualified with the 'restrict'
keyword.
Note that this form of declaration has no effect on the semantics of
the function. The function declaration, and its semantics, are just
the same as if the uses of 'restrict' were removed.
Note that Tim's critique or restrict in May 2023 is very similar to the critique of the similar noalias proposal in messageid <[email protected]>
by someone highly respected in this group. That was posted 35 years
ago.
That someone was even opposed to const, for some good reasons.
The present issue reveals a design flaw in the C type system:
that qualifiers on function parameters don't matter.
They should, though.
void f(const int);
void f(int);
should be incomaptible and diagnosed! Someone thought, at some point, that those qualifiers which existed then (const, volatile) only affect the
function definition locally, and not its interface semantics.
So, it probably seemed like a marvellous idea. I know! Let's make
qualifiers on parameters not matter, as if they were not there.
Then you can make a parameter const, if that makes sense in
the function definition, without disturbing the declaration.
But restrict is not like this. When a pointer parameter is restrict, it
changes the semantics in a way that is very much relevant to the caller.
Here is how it should work:
The rule should be that only const and volatile qualifiers do not matter
on a function parameter, as far as type compatibility and composite type
is concerned. The restrict qualifier should matter, and future
qualifiers that may be introduced have to be considered on a
case-by-casde basis.
If a function definition is changed to include a restrict parameter,
that should render it incompatible with the declaration.
The declaration is then updated, and makes a semantic difference to the
calls; the calls become undefined behavior if they pass overlapping
objects. This can be detected at translation time and diagnosed, with
the translation unit then being rejected, even if all that is known bout
the function is its declaration with restrict parameters.
Alternative rules:
// All declarations must be identical in restrict qualification:
int f(const char * restrict);
int f(const char *); // error: incompatible redeclaration
// Definition is allowed to change restrict qualification
int f(const char *p) // OK
{
// type of f here is without the restrict.
// Only the parameter itself lacks the qualifier.
// If f recurses, restrict does not apply to call.
}
// type of f in this scope is *with* the restrict from decl.
In other words, the type doesn't compose with regard to restrict
qualification. Only a definition can change the restrict-qualification
of a parameter, and then in taht definition's own scope, its own
restrict qualifiers (or lack thereof) apply, and determine the type of
the function, not only the local parameters.
--
TXR Programming Language:
http://nongnu.org/txr
Cygnal: Cygwin Native Application Library:
http://kylheku.com/cygnal
Mastodon: @
[email protected]
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)