Date: Sun, 27 Apr 2025 10:53:26 +0000
> I'm not sure how you could do that other than maybe dropping function pointer comparison altogether except against nullptr.
I don't see a reason not to do that.
________________________________
From: Std-Discussion <std-discussion-bounces_at_[hidden]> on behalf of Jennifier Burnett via Std-Discussion <std-discussion_at_[hidden]>
Sent: Sunday, April 27, 2025 12:06:36 PM
To: std-discussion_at_[hidden] <std-discussion_at_[hidden]>; Nate Eldredge via Std-Discussion <std-discussion_at_[hidden]>
Cc: Jennifier Burnett <jenni_at_[hidden]>
Subject: Re: [std-discussion] Guarantees over addresses from function pointers created from lambda
I have worked on one codebase that something did this, for basically the same reason as the original example in this thread where they were rolling their own vtables for a type erased callback storage class, and they used a sentinel function to identify trivially copyable and trivially destructible classes to skip the function call. Nullptr was used to indicate an empty callback.
In both cases there were branch mispredictions happening on the check for the sentinel (plus additional instructions were needed to form the sentinel address) and it was just faster to call an empty function for the trivial destructor and have the trivial copy just use a function that called memcpy. The original company as far as I'm aware didn't merge our changes back into their codebase.
I've also worked on a different codebase which was using a function pointer to a templated function as a form of cheap RTTI on a type erased container (games, so nobody ships codebases with it enabled).
Ideally if it was dropped you'd want existing code relying on it to break at compile time, I'm not sure how you could do that other than maybe dropping function pointer comparison altogether except against nullptr.
On 27 April 2025 03:49:37 BST, Nate Eldredge via Std-Discussion <std-discussion_at_[hidden]> wrote:
On Apr 26, 2025, at 11:34, Andrey Semashev via Std-Discussion <std-discussion_at_[hidden]> wrote:
The point is, even if the standard guarantees this [pointers to different functions comparing unequal], it's probably not a
good idea to rely on this in practice.
This being so, does anyone know if there has ever been a formal proposal to weaken this rule, or informal study of doing so?
I can certainly see the aesthetic argument for the rule, but I wonder how much real-life code actually relies on it. The only specific use case I can see is sentinels:
void sentinel() { }
void foo(void (*callback)()) {
if (!callback) {
proceed_without_callback();
} else if (callback == sentinel) {
something_special();
} else {
callback();
}
}
but it seems like a modern C++ programmer would rather do that with std::variant or some other way. So I wonder if anyone has studied the impact on existing code bases of dropping this guarantee.
I don't see a reason not to do that.
________________________________
From: Std-Discussion <std-discussion-bounces_at_[hidden]> on behalf of Jennifier Burnett via Std-Discussion <std-discussion_at_[hidden]>
Sent: Sunday, April 27, 2025 12:06:36 PM
To: std-discussion_at_[hidden] <std-discussion_at_[hidden]>; Nate Eldredge via Std-Discussion <std-discussion_at_[hidden]>
Cc: Jennifier Burnett <jenni_at_[hidden]>
Subject: Re: [std-discussion] Guarantees over addresses from function pointers created from lambda
I have worked on one codebase that something did this, for basically the same reason as the original example in this thread where they were rolling their own vtables for a type erased callback storage class, and they used a sentinel function to identify trivially copyable and trivially destructible classes to skip the function call. Nullptr was used to indicate an empty callback.
In both cases there were branch mispredictions happening on the check for the sentinel (plus additional instructions were needed to form the sentinel address) and it was just faster to call an empty function for the trivial destructor and have the trivial copy just use a function that called memcpy. The original company as far as I'm aware didn't merge our changes back into their codebase.
I've also worked on a different codebase which was using a function pointer to a templated function as a form of cheap RTTI on a type erased container (games, so nobody ships codebases with it enabled).
Ideally if it was dropped you'd want existing code relying on it to break at compile time, I'm not sure how you could do that other than maybe dropping function pointer comparison altogether except against nullptr.
On 27 April 2025 03:49:37 BST, Nate Eldredge via Std-Discussion <std-discussion_at_[hidden]> wrote:
On Apr 26, 2025, at 11:34, Andrey Semashev via Std-Discussion <std-discussion_at_[hidden]> wrote:
The point is, even if the standard guarantees this [pointers to different functions comparing unequal], it's probably not a
good idea to rely on this in practice.
This being so, does anyone know if there has ever been a formal proposal to weaken this rule, or informal study of doing so?
I can certainly see the aesthetic argument for the rule, but I wonder how much real-life code actually relies on it. The only specific use case I can see is sentinels:
void sentinel() { }
void foo(void (*callback)()) {
if (!callback) {
proceed_without_callback();
} else if (callback == sentinel) {
something_special();
} else {
callback();
}
}
but it seems like a modern C++ programmer would rather do that with std::variant or some other way. So I wonder if anyone has studied the impact on existing code bases of dropping this guarantee.
Received on 2025-04-27 10:53:29