C++ Logo

std-discussion

Advanced search

Re: Guarantees over addresses from function pointers created from lambda

From: Andrey Semashev <andrey.semashev_at_[hidden]>
Date: Sat, 26 Apr 2025 20:34:08 +0300
On 26 Apr 2025 20:17, Nate Eldredge via Std-Discussion wrote:
>
>
>> On Apr 26, 2025, at 10:22, Federico Kircheis via Std-Discussion <std-
>> discussion_at_[hidden]> wrote:
>>
>> On 26/04/2025 4:05 pm, mauro russo wrote:
>>>
>>
>>> > * if different function can have the same address, the class if
>>> > broken, (the lifetime of the previous object did not end correctly)
>>> This should be something never happening. It cannot make sense
>>> to have different functions at the same address.
>>
>> IMHO it makes sense that
>>
>> void foo(){}
>> void bar(){}
>>
>> can have the same address, similarly to how identical string literals
>> can have the same address; I was not sure if such optimization was
>> allowed.
>
> I think it's forbidden by expr.eq p3.2-3.3 (https://eel.is/c++draft/
> expr.eq#3.2 <https://eel.is/c++draft/expr.eq#3.2>). Two function
> pointers compare equal if and only if they "point to the same function".
> I think it's clear that foo() and bar() are not "the same function",
> even if they perform the same behavior.
>
> String literals have an explicit exemption from this rule per
> intro.object p9 (https://eel.is/c++draft/intro.object#9 <https://eel.is/
> c++draft/intro.object#9>).
>
> Somewhat related, clang does a "controversial" optimization where, if a
> function would unconditionally cause UB if called, the compiler emits a
> label for it but no code, not even a return instruction. As such, the
> next function compiled can end up at the same address. See https://
> godbolt.org/z/775s6e4vv <https://godbolt.org/z/775s6e4vv> for an
> example. This does seem like a clear violation of expr.eq p3, but it's
> been unfixed for a long time.

While the standard is pretty clear that two pointers to a function shall
only compare equal if they point to the same function, the rule has been
violated by compilers rather often. In both ways. For example, two
pointers to the same function may compare unequal if the function ends
up compiled in different shared objects with local visibility (e.g. if
the function is defined in a header that gets included in both shared
objects during compilation). And some compilers (MSVC, possibly others)
also implement an optimization to merge equivalent bodies of different
functions in the compiled binary, thus reducing the binary size. This
would result in addresses of foo and bar defined above to compare equal.

The point is, even if the standard guarantees this, it's probably not a
good idea to rely on this in practice.

Received on 2025-04-26 17:34:13