C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Function overload set type information loss

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Thu, 1 Aug 2024 00:33:03 +0200
śr., 31 lip 2024 o 23:23 organicoman <organicoman_at_[hidden]> napisał(a):
>
>
>
>
> Problem is that you try to break C++ type system.
>
> You suggest:
> ```
> "PFvvE_d" == typeid(f<double>).name()
> ```
>
> And this same by analogy:
>
> ```
> "i_42" == typeid(42).name()
> ```
>
> Nope that's a plain prvalue int. There is no type information lost in the value 42.
>
> Why only template parameters are propagated, not function `f` itself too?
> I even recall that Rust does something like this, each function has
> its own type that is
> inheriting from type based on this function signature
> (thanks this you can still have function pointers).
>
> Besides your suggestion that `auto x` can propagate more than normal
> type and value
> is DoA as it would be breaking change, consider this simple code:
>
> ```
> template<typename T>
> void foo() { }
>
> void foo2() { }
>
> int bar(auto f)
> {
> static int i = 0;
> return ++i;
> }
>
> int main()
> {
> bar(&foo2);
> bar(&foo<int>);
> bar(&foo<double>);
> bar(&foo<float>);
> return bar(&foo<long>);
> }
> ```
>
> It needs to return `5`. And because of this you can't do any magic in
> `bar` to extract additional
>
> It will print 5, there is no type information manipulated inside bar, thus the compiler will stamp the usual code.
>
> information from `f` argument even if the compiler knows it as it
> would be an ODR violation.
>
> The effective type will be used only when the user specify it inside a block scope.
> That way the compiler is notified to track the real type provided by the user, and process the information discrad it after if it proves necessary.
> Type manipulation is the compiler business.
> Value manipulation is the runtime business.

With blocks exactly? Consider this functions:

```
//... many foo

void foo98(auto a)
{
   foo97(a);
}

void foo99(auto a)
{
   foo98(a);
}

int* foo100(auto a)
{
    static int i = 0;
    foo99(a);
    return &i
}

template<typename T>
void bar(){ }

int main()
{
    return foo100(&bar<int>) == foo100(&bar<long>);
}
```

Is this returning true? How many functions do you need to examine to
know it? based on your definition, all.
This is brittle sooo much that it could be considered broken. Some
helper template functions deep in
some meta-library you use break your reasonable code because it used
your new operator for logging.

Beside you write in other email:

>
>
> #include <vector>
> template<typename T>
> inline constexpr int Var= 123;
>
> struct S{
> template<typename T>
> using meta_int = effdecltype(Var<T>);
> meta_int m_val;
> template<typename T>
> constexpr S() noexcept
> : m_val (Var<T>)
> { }
> };

How on earth can it be `sizeof(S) == sizeof(int)`?
Even more, you confuse yourself by writing `meta_int m_val;` that does
not make sense at all.
Type aliases can't be member fields of struct, you add `effdecltype`
but I do not remember
you said that you change how type aliases work.
And where is "references to a global constexpr variable"? If there is
any reference there
then by definition it needs to be `sizeof(S) > sizeof(void*) > sizeof(int)`.


I think instead of butchering C++ type system you should simply use
`std::meta::info`
that is clear and logical, without any handwaving.


Besides, what is the point of this anyway? You plan to make
compilation time of nearly
all template code a lot worse for what?


> >
> > On Wed, Jul 31, 2024 at 6:21 AM organicoman via Std-Proposals <std-proposals_at_[hidden]> wrote:
> >>
> >>
> >>
> >>
> >>
> >> Sent from my Galaxy
> >>
> >>
> >>
> >> You have been the one who wanted to different types with decltype and effective_decltype.
> >>
> >>
> >>
> >> Why are you complaining?
> >>
> >> The correct answer in your example must be in the following form:
> >>
> >> // one plausible mangled name
> >>
> >> PFvvE_i <--- f<int>
> >>
> >> PFvvE_d <--- f<double>
> >>
> >> the radix PFvvE is the same denoting the same apparent type, and different tags { _i, _d }, to denote the effective type.
> >>
> >> Likewise, the type information is not lost. And you can trace back to what you have called.
> >>
> >>
> >> Anyway, I think we touched everything in this thread, and thanks to you and Tiago i found a corner case, but solved it.
> >>
> >> I think it is time to compile some wording and post it here, maybe it will be more clear.
> >>
> >>
> >> -----Ursprüngliche Nachricht-----
> >> Von: organicoman <organicoman_at_[hidden]>
> >> Gesendet: Mi 31.07.2024 10:50
> >> Betreff: Re: [std-proposals] Function overload set type information loss
> >> An: Sebastian Wittmeier via Std-Proposals <std-proposals_at_[hidden]>;
> >> CC: Sebastian Wittmeier <wittmeier_at_[hidden]>;
> >>
> >>
> >>
> >> With function pointers you can achieve something like; in most cases even this is only possible at runtime:
> >>
> >>
> >>
> >>
> >>
> >> PFvvE <--| do you see the problem here
> >> PFvvE <--| f<int>,f<double>, yet the same name
> >> Just one function f.
> >> Just one function f.
> >> f<double>
> >> f<int>
> >>
> >> In "type theory" that's not correct.
> >> Two entity of different signature must have
> >> different types. Otherwise a many to one
> >> relationship takes place.
> >>
> >> --
> >> Std-Proposals mailing list
> >> Std-Proposals_at_[hidden]
> >> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
> >
> > --
> > Std-Proposals mailing list
> > Std-Proposals_at_[hidden]
> > https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2024-07-31 22:33:16