Date: Wed, 19 Mar 2025 20:52:56 +0100
śr., 19 mar 2025 o 10:18 Hans Åberg via Std-Proposals
<std-proposals_at_[hidden]> napisał(a):
>
>
> > On 19 Mar 2025, at 00:16, Andre Kostur <andre_at_[hidden]> wrote:
> >
> > Please provide a specific concrete example of this in play to showcase how this attribute would be significantly better than all of the existing alternatives.
>
> The example I mentioned first in this thread is:
> https://gcc.gnu.org/pipermail/gcc-help/2025-January/143945.html
> GCC has the type std::float128_t on MacOS, but not the functions, as they rely on the C library which comes from Clang which does not have this type implemented.
>
> Assume that GCC has the declaration:
> namespace std{
> [[unimplemented]] std::float128_t modf(std::float128_t, std::float128_t*);
> }
>
> Then it is possible to implement it in GCC, assuming there is also a new “unimplemented” macro, by:
> #if QUADMATH_H // Or something
> #include <quadmath.h>
> #endif
>
> namespace std {
> #if unimplemented(modf(std::float128_t, std::float128_t*)) // Problem with “,” here
> std::float128_t modf(std::float128_t x, std::float128_t* y) {
> __float128 y0;
> __float128 r = modfq(x, &y0);
> *y = y0;
> return r;
> }
> #endif
> }
>
> Then it will add the function definition on platforms where it is unimplemented but having the <quadmath.h> library, but add nothing if it is implemented.
>
> If Clang later adds support for float128 in its C library, then GCC will also will have it from this library, rather than the added implementation.
>
Nitpicking:
> // Problem with “,” here
why is this a "problem"? Whole point of `()` in macros is to stop
macro expansion from grouping tokens to separate arguments on `,` .
More serious question: how can preprocessor know what function is
implemented or not?
You can run prepreocson on a file that is not C/C++ in the first place.
Only way preprocessor can know anything about C++ is predefined macros like:
```
#if defined(__modf__float128)
// your code
#endif
```
Right now the only sense I see in this proposal is more a
"placeholder" function for header only libraries.
This will work only in one TU and with `inline` functions.
You can define:
```
void foo() = unimplemented;
inline void bar() { foo(); }
```
and this is valid code, but when you try odr-used `bar` (call or get
address) then you get an error that refers to an unimplemented
function.
This effectively makes it too ` = unimplemented;` abd propagates up to
other callers function, effectively poisoning everything.
But when you add:
```
void foo() { /**/ }
```
Then you are free to call `bar`.
But even if it work this way it will have lot of corner cases like:
```
static_assert(unimplemented(bar));
void foo();
static_assert(unimplemented(bar) == false);
```
Another thing is, this is asking for ODR violations as you grab the
header with `bar` but forget one with the definition of `foo`.
This could easily change code `if constexpr (unimplemented(bar))`.
Probably any way of quarrying `unimplemented` or SFINAE it should be banned.
Another problem is how far it can propagate. As you can add another
inline function:
```
inline void fiz() { static Func foo = &bar; }
```
Technically this is another inline function that could be "poisoned"
but this `static` value mean "leaking"
`bar` address and now we need to enforce `unimplemented`? Or we can
still wait unit function like this is called
from `main`. Knowing the "creative" way C++ can be abused, this will
probably quickly become a halting-problem :)
Right now a real life example where I could see this used could be
some micro controllers.
You have generic library that is used for many kinds of hardware and
peripheries but
in most cases you will use 1% of code from this library and its need
some specific hooks
to your proprietary hardware.
```
#include "lib_micro.h"
void lib_micro_logs(const char*) {}
void lib_micro_exit(int) {}
void lib_micro_abort() {}
void lib_micro_set_pin(int, int) {}
//const char* lib_micro_get_config(const char*) {}
```
Now you can use neary all functions from lib aside from ones that
indirectly try to call `lib_micro_get_config`.
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
<std-proposals_at_[hidden]> napisał(a):
>
>
> > On 19 Mar 2025, at 00:16, Andre Kostur <andre_at_[hidden]> wrote:
> >
> > Please provide a specific concrete example of this in play to showcase how this attribute would be significantly better than all of the existing alternatives.
>
> The example I mentioned first in this thread is:
> https://gcc.gnu.org/pipermail/gcc-help/2025-January/143945.html
> GCC has the type std::float128_t on MacOS, but not the functions, as they rely on the C library which comes from Clang which does not have this type implemented.
>
> Assume that GCC has the declaration:
> namespace std{
> [[unimplemented]] std::float128_t modf(std::float128_t, std::float128_t*);
> }
>
> Then it is possible to implement it in GCC, assuming there is also a new “unimplemented” macro, by:
> #if QUADMATH_H // Or something
> #include <quadmath.h>
> #endif
>
> namespace std {
> #if unimplemented(modf(std::float128_t, std::float128_t*)) // Problem with “,” here
> std::float128_t modf(std::float128_t x, std::float128_t* y) {
> __float128 y0;
> __float128 r = modfq(x, &y0);
> *y = y0;
> return r;
> }
> #endif
> }
>
> Then it will add the function definition on platforms where it is unimplemented but having the <quadmath.h> library, but add nothing if it is implemented.
>
> If Clang later adds support for float128 in its C library, then GCC will also will have it from this library, rather than the added implementation.
>
Nitpicking:
> // Problem with “,” here
why is this a "problem"? Whole point of `()` in macros is to stop
macro expansion from grouping tokens to separate arguments on `,` .
More serious question: how can preprocessor know what function is
implemented or not?
You can run prepreocson on a file that is not C/C++ in the first place.
Only way preprocessor can know anything about C++ is predefined macros like:
```
#if defined(__modf__float128)
// your code
#endif
```
Right now the only sense I see in this proposal is more a
"placeholder" function for header only libraries.
This will work only in one TU and with `inline` functions.
You can define:
```
void foo() = unimplemented;
inline void bar() { foo(); }
```
and this is valid code, but when you try odr-used `bar` (call or get
address) then you get an error that refers to an unimplemented
function.
This effectively makes it too ` = unimplemented;` abd propagates up to
other callers function, effectively poisoning everything.
But when you add:
```
void foo() { /**/ }
```
Then you are free to call `bar`.
But even if it work this way it will have lot of corner cases like:
```
static_assert(unimplemented(bar));
void foo();
static_assert(unimplemented(bar) == false);
```
Another thing is, this is asking for ODR violations as you grab the
header with `bar` but forget one with the definition of `foo`.
This could easily change code `if constexpr (unimplemented(bar))`.
Probably any way of quarrying `unimplemented` or SFINAE it should be banned.
Another problem is how far it can propagate. As you can add another
inline function:
```
inline void fiz() { static Func foo = &bar; }
```
Technically this is another inline function that could be "poisoned"
but this `static` value mean "leaking"
`bar` address and now we need to enforce `unimplemented`? Or we can
still wait unit function like this is called
from `main`. Knowing the "creative" way C++ can be abused, this will
probably quickly become a halting-problem :)
Right now a real life example where I could see this used could be
some micro controllers.
You have generic library that is used for many kinds of hardware and
peripheries but
in most cases you will use 1% of code from this library and its need
some specific hooks
to your proprietary hardware.
```
#include "lib_micro.h"
void lib_micro_logs(const char*) {}
void lib_micro_exit(int) {}
void lib_micro_abort() {}
void lib_micro_set_pin(int, int) {}
//const char* lib_micro_get_config(const char*) {}
```
Now you can use neary all functions from lib aside from ones that
indirectly try to call `lib_micro_get_config`.
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2025-03-19 19:53:07