C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Guarantees over addresses from function pointers created from lambda

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Tue, 29 Apr 2025 19:58:18 -0400
On Mon, Apr 28, 2025 at 1:02 PM Brian Bi <bbi5291_at_[hidden]> wrote:

> On Mon, Apr 28, 2025 at 12:56 PM Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
> wrote:
>
>> On Sun, Apr 27, 2025 at 1:22 PM Brian Bi via Std-Proposals <
>> 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
>> <https://github.com/bloomberg/bde/blob/main/groups/bsl/bsltf/bsltf_templatetestfacility.h#L1089-L1093>
>> ):
>> 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]
<https://cplusplus.github.io/CWG/issues/2753.html>*, 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

>

Received on 2025-04-29 23:58:32