C++ Logo

std-proposals

Advanced search

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

From: Breno Guimarães <brenorg_at_[hidden]>
Date: Fri, 2 Aug 2024 19:25:09 -0300
So it doesn't work for multiple translation units?

Em sex., 2 de ago. de 2024 19:16, organicoman via Std-Proposals <
std-proposals_at_[hidden]> escreveu:

> Your solution requires at compile time information that is only available
> at runtime.
>
> I don't understand what runtime data you are referring to.
>
> In the algorithm explained before. All the data, that the compiler's
> pre-pass is manipulating, are compile time data.
> At the level of a translation unit. A function with *orthogonal template
> parameters* (foo<T>)
> cannot exist unless you instantiate it.
> Add to that, the function is tagged as per the algorithm, so it is prone
> to record the types it was instantiated for.
> But as an optimization, the compiler will not record the list of *orthogonal
> **template parameters* unless it sees that some variable is using it,
> otherwise no need to generate any code.
> The compiler confirmed that by the usage of the effdecltype operator
> inside the template argument of the vector in the example.
> Every time you instantiate foo with a type, you have to write it
> explicitly in the source code.
> foo<int>, foo<double>...etc
> Next to that, the address of a function is a constexpr value, you can use
> it as a non-type template parameter.
> So as a summary, the list of *orthogonal template parameters* is
> fetchable from the source code, and the address of the instances is
> constexpr value.
> These are the ingredients to make the algorithm work.
>
> Even if the compiler could trace data across any type of data container
> (which it won't),
>
> It doesn't need to, because the information needed is the *orthogonal
> template parameters* not the number of elements in the container.
> You can have 100 element of type foo<int>, but the list of *orthogonal
> template parameters* is only { int }
> It's like you are counting how many instances of foo<T> you have in that
> translation unit.
>
> datapoints in container could take the form of any possible combination
> on any position and be influenced to translation units not visible at
> compile time. But for your solution to work it requires a fix layout (which
> in practice doesn't happen) and perfect observability.
> This is not a problem that needs to be solved, it's just how things work.
>
> Let me reiterate.
> Look at this snippet:
>
> vec.push_back(&foo<int>);
> int random;
> cin >> random;
> while(random - -) vec.push_back(&foo<char>);
> cin >> random;
> random = min(random, vec.size());
> while(random - -) vec.pop_back();
>
> As you can see, i cannot tell nor track the vector size. But it is
> irrelevant, because i have only two function pointer => { int, char }
> And by consequence my switch statment will contain only two cases:
>
> case &foo<int>:
> return __Xic_foo_eff_{ &foo<int>, int(0) };
> case &foo<char>:
> return __Xic_foo_eff_{ &foo<char>, char(0) };
>
> The two case lables are constexpr values known at compile time.
>
> You cannot resolve this problem without appending extra data to containers
> that is used to inform about the nature of the data. And you cannot solve
> this without a runtime check and control flow to browse for the right
> handler.
> This is a problem of distinguishability and computability, it is not
> something you can solve, it's a consequence of math as described by Shannon.
>
> That's why std:any has additional data related to runtime type
> information, and that's why it always needs some form of selection or hash
> table or equivalent.
>
> Well, i just proved to you that i don't need that data, and that this
> approach is plausibly more effecient and safe.
> Let's try to stretch it more, shall we?
>
> The way it's already done is already how this problem should be solved, no
> new feature necessary. What you are proposing requires the suspension of
> the laws of physics.
>
>
> ------------------------------
> *From:* organicoman <organicoman_at_[hidden]>
> *Sent:* Friday, August 2, 2024 9:44:09 PM
> *To:* Tiago Freire <tmiguelf_at_[hidden]>; std-proposals_at_[hidden]
> <std-proposals_at_[hidden]>
> *Subject:* Re: [std-proposals] Function overload set type information loss
>
>
>
>
> And also unimplementable...
> But you don't have to take my word for it, you can try it yourself.
>
> But ... that's the whole purpose of this thread.
> Putting down an idea in form of a paper, or an algorithm and tackle any
> contradiction it raise untill we hit the wall or we make it through.
> And we have just started agreeing about the core idea. Which is
> Adding an operator that does overload dispatch and code generation...etc
>
> If it is not implementable, then point where, i will work on it...
>
> ------------------------------
> *From:* Std-Proposals <std-proposals-bounces_at_[hidden]> on behalf
> of organicoman via Std-Proposals <std-proposals_at_[hidden]>
> *Sent:* Friday, August 2, 2024 9:15:36 PM
> *To:* organicoman via Std-Proposals <std-proposals_at_[hidden]>
> *Cc:* organicoman <organicoman_at_[hidden]>
> *Subject:* Re: [std-proposals] Function overload set type information loss
>
> Hello Gašper,
> Since participants are starting to get what I am talking about, then allow
> me to answer your pending question.
> This is what you've said in previous post.
>
> There is another fundamental misunderstanding here.
>
> The feature calls to "record all the orthogonal template parameters".
>
> While that's not what that word means, I think regardless it's asking for
> global enumeration. C++ has a separate linking model. All the
> types/functions are not known within a single unit. The xunion is
> impossible to compute.
>
> This is a sister problem to what Jason is highlighting.
>
> When i was describing my algorithm, i left a big X mark, hoping that
> someone will ask me, if people were attentive.
> Line:
> 4-b-
> switch
> *.....
> * inside function body: goto X
>
> Then I left a hint at the bottom of the post in a form of code comment
>
> double var2 = *reinterpret_cast<double*>
> ((reinterpret_cast<char*>(&(useType()))+sizeof(int)); // int since
> __X_index is int. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> ^^^^^
>
> The __X_index is not of type int but of type void*, the unnamed struct
> that the compiler generate becomes:
> struct __Xidfc_foo_eff
> {
> void* __X_index;
> union
> { int __Xi; double __Xd ; float __Xf; char __Xc };
> };
>
> Since the compiler tagged useType function, as described by the
> algorithm, then after finishing recording the orthogonal template
> parameters, it replaces the body with the following.
>
> auto useType(effdecltype(foo) f)
> {
> f();
> switch(f)
> {
> case &f<int>: //<- the pointer value
> return __Xidfc_foo_eff{(void*) &f<int>, int(0)};
>
> case &f<double>:
> return __Xidfc_foo_eff{(void*) &f<double>, double(0)};
>
> case &f<float>:
> return __Xidfc_foo_eff{(void*) &f<float>, float(0)};
>
> case &f<char>:
> return __Xidfc_foo_eff{(void*) &f<char>, char(0)};
> }
> }
>
> Pointers are comparable for equality.
>
> As you can see, you can capture the xunion.... right? There is no
> fundamental misunderstanding ...
> Plus everything is done by the compiler, there is no global map, no find
> algorithm, no type hashs, no type erasure (heap allocation), no manual
> intervention. All is automated at compile-time.
>
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2024-08-02 22:25:22