Date: Fri, 17 Apr 2026 18:43:00 +0800 (CST)
At 2026-04-17 14:36:41, "Sebastian Wittmeier" <wittmeier_at_[hidden]> wrote:
Interceptors make the life easier for some.
So, it just makes the job harder for everyone else?
But they also take away from the purity of the language.
That's another subjective assertion.
They make reasoning about it more involved, because another function may be called. They change the underlying programming model to a more imperative one.
Interceptors are declared right on the function (in other languages). If you have access to the function signature, you can definitely see the Interceptors, so you'll know for sure if another function is being triggered.
If you can't see it, why should you care? Unless there's a bug in the implementation.
Depending on how they are implemented
- they cannot be easily combined with other Interceptors to the same function - at least there are ordering issues
Interceptors are always just layered one on top of another. I've honestly never seen them actually composed together.
- it is a static facility, many would prefer runtime configuration
That's another subjective assertion. Being able to implement both static and runtime features is progress. Use whichever you prefer.
- many would prefer object-oriented wrappers, which are easier to create with reflection and meta-programming
Reflection is less efficient than Interceptors. By the way, we are discussing Interceptors, so why did you bring up Reflection? It feels like you're not really familiar with either of them.
- they possibly violate the access model (private+protected) of classes
Let the compiler tell the developer that Interceptors are private or protected. You can't possibly expose them to everyone.
- they may interact with contracts, if they change preconditions
If that happens, isn't it a compiler bug?
- they may badly interact with libraries
Function calls within a single thread are executed sequentially, unless the code written in the Interceptors has bugs or serious logic issues.
- many would have done interceptors a different way, perhaps even the implementors
I'm providing one implementation, but others can too. In my example, there's only one valid and correct way to do it¡ªif you write it any other way, the code won't run or it'll just crash.
Even if you get a good solution with your proposal, there will always be compromises and different opinions how the language should look like.
Different proposals are highly welcome, so we can compare them.
Just describe usages and who uses and needs them; and why it should be standardized instead of each implementation having their own Interceptors. Describe which facilities the existing implementations have.
Who doesn't use them? If you mean they aren't being used, well, Java and Python are using them.
Concrete use cases include: Authentication & Authorization, Logging & Monitoring, Validation & Sanitization, Global Exception Handling, Caching
Since you mentioned that many people have their own Interceptor solutions, give me an example.
And please skip the mature solutions like g++ --wrap or detours.
My compile-time solution is as follows:
template <class Func, class ...Args>
Func __wrap(Func real_send)
{
return [real_send](Args&&... args) -> decltype(real_send(args...))
{
do_something(std::forward<Args>(args)...);
return real_send(std::forward<Args>(args)...);
};
}
[[hook __wrap]] // Compile time: Directly renames real_send to real_send#__line__ (appending the line number or using other means to avoid conflicts). Note that this is not a redirection.
int real_send(int fd, const void *buf, size_t len, int flags) // Here, it essentially acts as const real_send = __wrap(real_send#__line__)
{
return send(fd, buf, len, flags);
}
Interceptors make the life easier for some.
So, it just makes the job harder for everyone else?
But they also take away from the purity of the language.
That's another subjective assertion.
They make reasoning about it more involved, because another function may be called. They change the underlying programming model to a more imperative one.
Interceptors are declared right on the function (in other languages). If you have access to the function signature, you can definitely see the Interceptors, so you'll know for sure if another function is being triggered.
If you can't see it, why should you care? Unless there's a bug in the implementation.
Depending on how they are implemented
- they cannot be easily combined with other Interceptors to the same function - at least there are ordering issues
Interceptors are always just layered one on top of another. I've honestly never seen them actually composed together.
- it is a static facility, many would prefer runtime configuration
That's another subjective assertion. Being able to implement both static and runtime features is progress. Use whichever you prefer.
- many would prefer object-oriented wrappers, which are easier to create with reflection and meta-programming
Reflection is less efficient than Interceptors. By the way, we are discussing Interceptors, so why did you bring up Reflection? It feels like you're not really familiar with either of them.
- they possibly violate the access model (private+protected) of classes
Let the compiler tell the developer that Interceptors are private or protected. You can't possibly expose them to everyone.
- they may interact with contracts, if they change preconditions
If that happens, isn't it a compiler bug?
- they may badly interact with libraries
Function calls within a single thread are executed sequentially, unless the code written in the Interceptors has bugs or serious logic issues.
- many would have done interceptors a different way, perhaps even the implementors
I'm providing one implementation, but others can too. In my example, there's only one valid and correct way to do it¡ªif you write it any other way, the code won't run or it'll just crash.
Even if you get a good solution with your proposal, there will always be compromises and different opinions how the language should look like.
Different proposals are highly welcome, so we can compare them.
Just describe usages and who uses and needs them; and why it should be standardized instead of each implementation having their own Interceptors. Describe which facilities the existing implementations have.
Who doesn't use them? If you mean they aren't being used, well, Java and Python are using them.
Concrete use cases include: Authentication & Authorization, Logging & Monitoring, Validation & Sanitization, Global Exception Handling, Caching
Since you mentioned that many people have their own Interceptor solutions, give me an example.
And please skip the mature solutions like g++ --wrap or detours.
My compile-time solution is as follows:
template <class Func, class ...Args>
Func __wrap(Func real_send)
{
return [real_send](Args&&... args) -> decltype(real_send(args...))
{
do_something(std::forward<Args>(args)...);
return real_send(std::forward<Args>(args)...);
};
}
[[hook __wrap]] // Compile time: Directly renames real_send to real_send#__line__ (appending the line number or using other means to avoid conflicts). Note that this is not a redirection.
int real_send(int fd, const void *buf, size_t len, int flags) // Here, it essentially acts as const real_send = __wrap(real_send#__line__)
{
return send(fd, buf, len, flags);
}
Received on 2026-04-17 10:43:11
