Date: Fri, 9 May 2025 10:31:10 -0400
THank you, Andrej, this is the right way so we can keep a record of the
feedback. We are grateful. Please keep it coming.
On Fri, May 9, 2025 at 4:36 AM Andrzej Krzemienski via SG19 <
sg19_at_[hidden]> wrote:
> Hi All,
> I am new to this group, so I do not know how such feedback should be
> delivered. I didn't have time to report the issue in yesterday's call, so
> let me do it over email.
>
> I think that it is a design question how the graph algorithms should
> respond to the "questionable" input values, such as non-existent vertex
> index, or not properly initialized function output parameters.
>
> Take for instance `dijkstra_shortest_paths` specified in wg21.link/p3128.
> It specifies:
>
> 1 Mandates:
> —(1.1) 0 <= source < num_vertices(graph) for the single-source version.
> —(1.2) 0 <= source < num_vertices(graph), for each source in sources, for
> the multi-source version.
> —(1.3) The weight function w must return a non-negative value.
>
> 2 Preconditions:
> —(2.1) distances[i] = shortest_path_infinite_distance() for 0 <= i <
> num_vertices(g).
> —(2.2) predecessors[i] = i for 0 <= i < num_vertices(g).
>
> 4 Throws:
> —(4.1) An out_of_range exception is thrown in the following cases:
> —(4.1.1) size(distances)< size(vertices(g))
> —(4.1.2) size(predecessor)< size(vertices(g))
> —(4.1.3) source is not in the range 0 <= source < num_vertices(graph).
> —(4.1.4) The weight function returns a negative value. This check is not
> made if the weight value type is an unsigned integral type.
>
> First of all, section "Mandates" only specifies compile-time checkable
> properties, and puts a hard requirement on the implementations to check the
> indicated conditions *at compile time*, for instance by using
> static_assert. The current conditions 1.1, 1.2, 1.3 are clearly not
> compile-time-checkable, so this is a bug in specification.
>
> But more importantly, regarding the condition `0 <= source <
> num_vertices(graph)` you have to make the choice:
> 1. Are the implementations *required* to check the condition and throw an
> exception when it is not met, so that the programmers can rely on this
> exception, and can "safely" pass bad indexes and expect predictable
> behavior?
> 2. Or are the implementations free to assume that the users always pass
> the correct values of `source`? This means that they can check the
> condition, but do not have to. If they check, they can either throw an
> exception, or launch a debugger, or terminate the program with a core dump.
> If the programmer passes the bad value of `source` they are guaranteed
> nothing, and it can even be undefined behavior.
>
> It is important that the paper documents this choice and the rationale for
> it. It is an important design decision. And then based on this decision,
> you either list the conditions under section "Preconditions" or you don't.
> If you list this under section "Precondition" it means #2 above, and you
> can no longer say that an exception is thrown in this case.
>
> The following links describe what Mandates and Precoonditions mean in
> detail:
> * https://eel.is/c++draft/description#structure.specifications-3.2
> * https://eel.is/c++draft/description#structure.specifications-3.3
>
> I recorded this issue in https://github.com/stdgraph/P1709/issues/113
>
> Regards,
> &rzej;
> --
> SG19 mailing list
> SG19_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg19
>
feedback. We are grateful. Please keep it coming.
On Fri, May 9, 2025 at 4:36 AM Andrzej Krzemienski via SG19 <
sg19_at_[hidden]> wrote:
> Hi All,
> I am new to this group, so I do not know how such feedback should be
> delivered. I didn't have time to report the issue in yesterday's call, so
> let me do it over email.
>
> I think that it is a design question how the graph algorithms should
> respond to the "questionable" input values, such as non-existent vertex
> index, or not properly initialized function output parameters.
>
> Take for instance `dijkstra_shortest_paths` specified in wg21.link/p3128.
> It specifies:
>
> 1 Mandates:
> —(1.1) 0 <= source < num_vertices(graph) for the single-source version.
> —(1.2) 0 <= source < num_vertices(graph), for each source in sources, for
> the multi-source version.
> —(1.3) The weight function w must return a non-negative value.
>
> 2 Preconditions:
> —(2.1) distances[i] = shortest_path_infinite_distance() for 0 <= i <
> num_vertices(g).
> —(2.2) predecessors[i] = i for 0 <= i < num_vertices(g).
>
> 4 Throws:
> —(4.1) An out_of_range exception is thrown in the following cases:
> —(4.1.1) size(distances)< size(vertices(g))
> —(4.1.2) size(predecessor)< size(vertices(g))
> —(4.1.3) source is not in the range 0 <= source < num_vertices(graph).
> —(4.1.4) The weight function returns a negative value. This check is not
> made if the weight value type is an unsigned integral type.
>
> First of all, section "Mandates" only specifies compile-time checkable
> properties, and puts a hard requirement on the implementations to check the
> indicated conditions *at compile time*, for instance by using
> static_assert. The current conditions 1.1, 1.2, 1.3 are clearly not
> compile-time-checkable, so this is a bug in specification.
>
> But more importantly, regarding the condition `0 <= source <
> num_vertices(graph)` you have to make the choice:
> 1. Are the implementations *required* to check the condition and throw an
> exception when it is not met, so that the programmers can rely on this
> exception, and can "safely" pass bad indexes and expect predictable
> behavior?
> 2. Or are the implementations free to assume that the users always pass
> the correct values of `source`? This means that they can check the
> condition, but do not have to. If they check, they can either throw an
> exception, or launch a debugger, or terminate the program with a core dump.
> If the programmer passes the bad value of `source` they are guaranteed
> nothing, and it can even be undefined behavior.
>
> It is important that the paper documents this choice and the rationale for
> it. It is an important design decision. And then based on this decision,
> you either list the conditions under section "Preconditions" or you don't.
> If you list this under section "Precondition" it means #2 above, and you
> can no longer say that an exception is thrown in this case.
>
> The following links describe what Mandates and Precoonditions mean in
> detail:
> * https://eel.is/c++draft/description#structure.specifications-3.2
> * https://eel.is/c++draft/description#structure.specifications-3.3
>
> I recorded this issue in https://github.com/stdgraph/P1709/issues/113
>
> Regards,
> &rzej;
> --
> SG19 mailing list
> SG19_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg19
>
Received on 2025-05-09 14:31:27