Date: Wed, 30 Apr 2025 07:40:38 +0200
How to possibly solve it?
We have pointers to the same object with different identity.
Either double indirection of function pointers (as data or code) or additional bits or bytes in the pointer, which are only used for comparison.
-----Ursprüngliche Nachricht-----
Von:Sebastian Wittmeier <wittmeier_at_[hidden]>
Gesendet:Mi 30.04.2025 07:36
Betreff:AW: [std-proposals] Guarantees over addresses from function pointers created from lambda
An:std-proposals_at_[hidden];
Perhaps for functions we have to separate address and identity.
But functions should be first-class citizens.
Separate address and identity for all or at least all 'read-only' objects?
That would also solve some cases with string literals and possibly constinit objects.
-----Ursprüngliche Nachricht-----
Von:Tiago Freire via Std-Proposals <std-proposals_at_[hidden]>
Gesendet:Mi 30.04.2025 07:30
Betreff:Re: [std-proposals] Guarantees over addresses from function pointers created from lambda
An:std-proposals_at_[hidden]; Brian Bi <bbi5291_at_[hidden]>;
CC:Tiago Freire <tmiguelf_at_[hidden]>;
I feel that function addresses at compile time are kind of broken. They can’t be reasoned the same way as regular values.
If:
constexpr auto fun = &foo;
is allowed and
static_assert(&f != &g);
is allowed and
uintptr_t fun_number = std::bit_cast<uintptr_t>(fun)
is allowed
then why not
constexpr uintptr_t fun_number = std::bit_cast<uintptr_t>(fun)
?
That is weird.
Because functions at compile time can’t have addresses, they have “pseudo-adresses”, it’s all just smoke and mirrors, utterly meaningless.
I would not be bothered by
static_assert( &f != &g); //ok
assert( &f != &g); //trouble town
but that is my opinion.
From: Std-Proposals <std-proposals-bounces_at_[hidden]> On Behalf Of Arthur O'Dwyer via Std-Proposals
Sent: Wednesday, April 30, 2025 1:58 AM
To: Brian Bi <bbi5291_at_[hidden]>
Cc: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>; std-proposals_at_[hidden]
Subject: Re: [std-proposals] Guarantees over addresses from function pointers created from lambda
On Mon, Apr 28, 2025 at 1:02PM Brian Bi <bbi5291_at_[hidden] <mailto:bbi5291_at_[hidden]> > wrote:
On Mon, Apr 28, 2025 at 12:56PM Arthur O'Dwyer <arthur.j.odwyer_at_[hidden] <mailto:arthur.j.odwyer_at_[hidden]> > wrote:
On Sun, Apr 27, 2025 at 1:22PM Brian Bi via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]> > wrote:
A function is not an object, it is a function.
There's no reason to reason about functions as if they were objects.
In https://github.com/bloomberg/bde/blob/main/groups/bsl/bsltf/bsltf_templatetestfacility.h#L1285
we use the fact that different functions have different addresses to produce 128 unique values of type `TemplateTestFacility::MethodPtr` (which is a typedef to a pointer to member function), which are then used to test e.g. containers that must work with various kinds of element types.
That's not quite right [although see below]. You don't rely on the fact that different functions have different addresses; you rely on the fact that functions with different behavior must necessarily have different addresses.
You use (here):
template <int IDENTIFIER>
int TemplateTestFacility_StubClass::method() {
return IDENTIFIER;
}
static_assert(&method<1> != &method<2>);
Ah, right. But I think the only reason we have to give them different behaviour is that MSVC does the standard-noncompliant merging by default. There are probably codebases somewhere that support only Unix, and use empty bodies, and we shouldn't break those users.
Hm, I'm very unsympathetic to the argument that "people might be relying on function addresses to be distinct and we don't want to break them." I'd like to break them if we could.
But I think we still run into a physical roadblock here:
int f(); int g();
static_assert(f != g); // definitely unequal at compile time, right?
int main() { return (f == g); } // but we want to permit them to be equal at run-time?!
The only way to avoid this inconsistency, IMHO, is to treat function addresses as potentially non-unique [entities], i.e., forbid mangling them into symbol names and forbid comparing them at compile-time. Which I think is too onerous. But I'd love to see that proposal anyway — maybe there would be appetite for it!
Such a proposal would definitely want to explore/discuss the status quo for inherited functions and especially inherited virtuals (thunks), where comparing their addresses is already pretty weird at the codegen level.
–Arthur
-- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2025-04-30 05:47:25