Date: Mon, 8 Jun 2026 12:33:27 +0100
On 08/06/2026 07:50, David Brown via Std-Proposals wrote:
> On 07/06/2026 23:49, Sebastian Wittmeier via Std-Proposals wrote:
>> It is an interesting direction. Probably needs (in my personal humble opinion) implementation and usage experience first.
>>
>> Some things I noticed:
>>
>> 1) What does non-recursing mean?
>>
>> If A calls B and B calls A, is A recursing?
>
> Yes (IMHO). If a call of "A" can lead to a new call of A, no matter how far down the line, it is recursive.
>
> A related concept that is very important in embedded systems is "re-entrant". A function is "re-entrant" if there can be more than one thread of execution in it at a time - by recursion, by multiple threads, or by interrupt handlers. If a function is not re-entrant, then the compiler can allocate static storage for local variables or make various other optimisations - on small and limited microcontrollers, this is can be a huge efficiency gain. (But to be realistic, the devices where this makes the biggest difference are not likely to be programmed in C++29.)
>
>>
>> 2) It is part of the type? inferred where definitions are visible? That is dangerous for types suddenly changing depending on the definition. What if some code sees the definition and other code only the declaration? ODR violation?
>>
>> 3) One can on purpose declare a function, which calls (and does not catch) throwing functions as noexcept. Either you are convinced, that the exception does not happen in practice or you are happy with the process terminating in case of an exception.
>>
>
> Yes, it is important to decide on responsibilities - and what happens if something goes wrong or is inconsistent.
>
>> 4) nonallocating could be important relative to a certain heap, other (e.g. thread-local) heaps may be okay. nonblocking could be in relation to certain other threads or by certain mutexes, others may be okay. non- recursing may be okay for a certain function (with bounded recursions) and not okay for other functions.
>
> To me, this all quickly explodes - there are so many possibilities that it would be infeasible to have keywords or other fixed terms here. Some of these annotations might be definable in a clear enough manner (like "recursive"), but others need a lot more flexibility. And people would want more - "does not access the filesystem", "accesses the filesystem but read only", etc. And they will want negations and combinations (somewhat like combining concepts). So I think to be useful, this very much has to be a system where developers can define their own annotations, combined with a set of standard annotations in the standard library.
>
> In order to avoid making C++ code even cluttered (how many people put "noexcept" on all functions that could have it? Few, I think, outside of library code), there would have to be a mechanism for using annotations without specifying them all explicitly. Combining annotations (again, like concepts) would help, as would attaching annotations to namespaces so that functions and classes inherit them as defaults.
>
>
> I don't think it will be easy to make a good annotation system here. But I think it could be very useful for safety, correctness and efficiency.
>
> David
>
>
It's difficult to annotate all constraints.
Not directly following, adding my comment, even when we disable exceptions when compiling, the C++ Standard Library a push_back() may fail, and std::terminate() will be called. For functional safety it's unsuitable that calls to std::terminate() are present in a safety critical system, libraries are potentially going to call it and stop the software when some unanticipated behaviour occurs at runtime.
Regards, Jonathan
> On 07/06/2026 23:49, Sebastian Wittmeier via Std-Proposals wrote:
>> It is an interesting direction. Probably needs (in my personal humble opinion) implementation and usage experience first.
>>
>> Some things I noticed:
>>
>> 1) What does non-recursing mean?
>>
>> If A calls B and B calls A, is A recursing?
>
> Yes (IMHO). If a call of "A" can lead to a new call of A, no matter how far down the line, it is recursive.
>
> A related concept that is very important in embedded systems is "re-entrant". A function is "re-entrant" if there can be more than one thread of execution in it at a time - by recursion, by multiple threads, or by interrupt handlers. If a function is not re-entrant, then the compiler can allocate static storage for local variables or make various other optimisations - on small and limited microcontrollers, this is can be a huge efficiency gain. (But to be realistic, the devices where this makes the biggest difference are not likely to be programmed in C++29.)
>
>>
>> 2) It is part of the type? inferred where definitions are visible? That is dangerous for types suddenly changing depending on the definition. What if some code sees the definition and other code only the declaration? ODR violation?
>>
>> 3) One can on purpose declare a function, which calls (and does not catch) throwing functions as noexcept. Either you are convinced, that the exception does not happen in practice or you are happy with the process terminating in case of an exception.
>>
>
> Yes, it is important to decide on responsibilities - and what happens if something goes wrong or is inconsistent.
>
>> 4) nonallocating could be important relative to a certain heap, other (e.g. thread-local) heaps may be okay. nonblocking could be in relation to certain other threads or by certain mutexes, others may be okay. non- recursing may be okay for a certain function (with bounded recursions) and not okay for other functions.
>
> To me, this all quickly explodes - there are so many possibilities that it would be infeasible to have keywords or other fixed terms here. Some of these annotations might be definable in a clear enough manner (like "recursive"), but others need a lot more flexibility. And people would want more - "does not access the filesystem", "accesses the filesystem but read only", etc. And they will want negations and combinations (somewhat like combining concepts). So I think to be useful, this very much has to be a system where developers can define their own annotations, combined with a set of standard annotations in the standard library.
>
> In order to avoid making C++ code even cluttered (how many people put "noexcept" on all functions that could have it? Few, I think, outside of library code), there would have to be a mechanism for using annotations without specifying them all explicitly. Combining annotations (again, like concepts) would help, as would attaching annotations to namespaces so that functions and classes inherit them as defaults.
>
>
> I don't think it will be easy to make a good annotation system here. But I think it could be very useful for safety, correctness and efficiency.
>
> David
>
>
It's difficult to annotate all constraints.
Not directly following, adding my comment, even when we disable exceptions when compiling, the C++ Standard Library a push_back() may fail, and std::terminate() will be called. For functional safety it's unsuitable that calls to std::terminate() are present in a safety critical system, libraries are potentially going to call it and stop the software when some unanticipated behaviour occurs at runtime.
Regards, Jonathan
Received on 2026-06-08 11:33:30
