• What is the point of restrict in fopen?

    From Kaz Kylheku@21:1/5 to All on Wed May 24 23:41:30 2023
    I've noticed that both arguments of fopen are restrict-qualified.

    What does this achieve?

    If I have:

    const char *path = "foobar";
    const char *mode = path + 6;

    FILE *f = fopen(path, mode);

    is the behavior undefined, since the mode pointer accesses
    something which is also accessed through path?

    What if the code is this:

    FILE *f = fopen("foobar", "r");

    and the compiler itself merges the two string literals so
    that they share storage?

    The arguments are treated as immutable by fopen, so what is
    the purpose of restrict?

    The benefit of restrict is that when an object is being modified through
    a restrict-qualified pointer, the implementation is not required to care whether the object is aliased through another object. Access through the
    other pointer can be cached as if that modification didn't happen.
    If aliasing is occurring, the behavior is undefined, allowing the
    implementor not to care about that situation.

    But the arguments to fopen must not be modified.

    How can fopen be made faster based on the assurance that the inputs do
    not overlap, (and is that really worth breaking programs?)

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Kaz Kylheku on Thu Jul 20 10:17:37 2023
    Kaz Kylheku <864-117-4973@kylheku.com> 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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jakob Bohm@21:1/5 to Tim Rentsch on Fri Jul 21 08:55:48 2023
    On 2023-07-20 19:17, Tim Rentsch wrote:
    Kaz Kylheku <864-117-4973@kylheku.com> 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 <7753@alice.UUCP>
    by someone highly respected in this group. That was posted 35 years
    ago.

    Enjoy

    Jakob
    --
    Jakob Bohm, CIO, Partner, WiseMo A/S. https://www.wisemo.com
    Transformervej 29, 2860 Søborg, Denmark. Direct +45 31 13 16 10
    This public discussion message is non-binding and may contain errors.
    WiseMo - Remote Service Management for PCs, Phones and Embedded

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Jakob Bohm on Sat Jul 22 05:37:15 2023
    On 2023-07-21, Jakob Bohm <jb-usenet@wisemo.com.invalid> wrote:
    On 2023-07-20 19:17, Tim Rentsch wrote:
    Kaz Kylheku <864-117-4973@kylheku.com> 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 <7753@alice.UUCP>
    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: @Kazinator@mstdn.ca

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Jakob Bohm on Tue Jul 25 05:37:22 2023
    Jakob Bohm <jb-usenet@wisemo.com.invalid> writes:

    On 2023-07-20 19:17, Tim Rentsch wrote:

    Kaz Kylheku <864-117-4973@kylheku.com> 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 <7753@alice.UUCP> [...]

    My comment wasn't a critique, just an observation.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Kaz Kylheku on Tue Jul 25 05:35:30 2023
    Kaz Kylheku <864-117-4973@kylheku.com> writes:

    On 2023-07-21, Jakob Bohm <jb-usenet@wisemo.com.invalid> wrote:

    On 2023-07-20 19:17, Tim Rentsch wrote:

    Kaz Kylheku <864-117-4973@kylheku.com> 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
    <7753@alice.UUCP> 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!

    A foolish consistency is the hobgoblin of little minds.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Tim Rentsch on Tue Jul 25 19:33:46 2023
    On 2023-07-25, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
    Kaz Kylheku <864-117-4973@kylheku.com> writes:

    On 2023-07-21, Jakob Bohm <jb-usenet@wisemo.com.invalid> wrote:

    On 2023-07-20 19:17, Tim Rentsch wrote:

    Kaz Kylheku <864-117-4973@kylheku.com> 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
    <7753@alice.UUCP> 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!

    A foolish consistency is the hobgoblin of little minds.

    I deserve that for starting with that silly bait,
    but I later acknowledged that the flexibility is necessary
    to be able to const-qualify a parameter in the definition
    without touching the declaration.

    Here is a realistic plan.

    Phase 1:

    Qualifiers except restrict are ignored in function
    declarators, are not part of the function type and do not
    participate in composition. The restrict qualifier is now
    part of the type. If a declaration restrict-qualifies a parameter, a redeclaration (or definition) need not. The composite type of the
    parameter will be restrict-qualified.

    Tolerance for the presence of const and volatile qualifiers on
    paramaters in prototype declarations is marked obsolescent.

    Phase 2:

    The obsolescence period introduced in Phasae 1 ends. Const and volatile qualifiers are no longer allowed on parameters in declarations; it is a diagnosable constraint violation. They are allowed in definitions only,
    and don't contribute to the function type declared.

    A new obsolescence period begins: situations in which multiple
    declarations of a function differ in the restrict-qualification of a
    parameter are considered obsolescent.

    Phase 3:

    Obsolescence period from Phase 2 ends: it is a constraint violation
    whenever a declaration or definition of a function differs
    from a previous declaration in the restrict qualification of
    a parameter.

    // Phase 1 Phase 2 Phase 3
    void f(const int); // obsol. error error
    //
    void f(char *restrict p); //
    void g(char *); //
    //
    void f(char *p) { } // obsol. error
    void g(char *restrict p) // obsol. error

    i.e. the language becomes sane. Bullshit code smells like qualifiers
    that do nothing become errors. If restrict is used to optimize a
    function in a way that affects the interface contract, that must be
    reflected in the declaration; it is not possible to use restrict
    in a definition, but omit that in a declaration.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Kaz Kylheku on Fri Aug 4 20:15:45 2023
    Kaz Kylheku <864-117-4973@kylheku.com> writes:

    On 2023-07-25, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:

    Kaz Kylheku <864-117-4973@kylheku.com> writes:

    On 2023-07-21, Jakob Bohm <jb-usenet@wisemo.com.invalid> wrote:

    On 2023-07-20 19:17, Tim Rentsch wrote:

    Kaz Kylheku <864-117-4973@kylheku.com> 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.

    [...]

    Here is a realistic plan.

    Phase 1:

    [...]

    Phase 2:

    [...]

    Phase 3:

    [...]

    Here is a simpler and better idea.

    Add a Recommended Practice that compilers provide an
    option to produce a diagnostic when a function
    parameter is restrict-qualified in the function
    definition but is not restrict-qualified in any other
    declaration of the function in the same compilation
    unit.

    And nothing more than that.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)