Date: Tue, 28 Apr 2026 07:35:57 +0100
On Mon, 27 Apr 2026, 22:43 Frederick Virchanza Gotham via Std-Proposals, <
std-proposals_at_[hidden]> wrote:
> Consider intercepting a call to a function such as 'printf'. Instead
> of parsing all the percentage signs individually, you just want to
> forward all the arguments on. So the interceptor should be totally
> agnostic to the signature of the target function -- totally oblivious
> to its return type and parameter types.
https://wg21.link/p2826 seems better.
Like this:
>
> #include <cstdio> // printf
> #include <chrono> // seconds
> #include <thread> // sleep_for
>
> [[interceptor]] void MyInterceptor(void) noexcept
> {
> // Sleep for 1 second before jumping to 'printf'
>
> std::this_thread::sleep_for( std::chrono::seconds(1) );
> goto -> std::printf;
> }
>
> int main(int const argc, char **const argv)
> {
> auto const fp = (decltype(std::printf)*)&MyInterceptor;
>
> fp("My favourite number is %i,\nand my favourite word is %s.\n",
> argc,
> argv[ argc - 1 ]);
> }
>
> And well here it is now working up on GodBolt:
>
> https://godbolt.org/z/6qqTrq6Wj
>
> I want to explain to compiler vendors just how easy it is to implement
> this new feature. Here's what you do:
>
> Step 1 - When the compile encounters a function with the attribute
> [[interceptor]], create a second function declaration with the same
> name but prepended with "__core_", and change the second declaration's
> return type from 'void' to 'void(*)(void)'. Compile the body of the
> function into the second declaration. (The original declaration will
> become a thunk).
>
> Step 2 - Inside the body of the interceptor function, the 'return'
> statement should instead be written as 'goto ->'.
>
> Step 3 - Emit a thunk with the name of the original function
> declaration and give it assembler as follows:
>
> push_all_arguments
> call __core_Func
> pop_all_arguments
> jmp target_function
>
> It really is that simple. And because the original function name is
> mangled before "__core_" is prepended, it also works with templates:
>
> https://godbolt.org/z/8bYja9zfn
>
> In the above GodBolt, the original function name is mangled as
> "_Z13MyInterceptorILi0EEvv", and so then the core becomes
> "__core__Z13MyInterceptorILi0EEvv". You can have multiple template
> instantiations:
>
> https://godbolt.org/z/exxz5vcGo
>
> Easy peasy. Here's what I've got so far for the GNU compiler patch:
>
> https://github.com/healytpk/gcc-thomas-healy/commit/tag_interceptor
>
> It's not perfect but it's a really good proof of concept.
>
> Note that for any given target CPU instruction set, such as x86_64,
> the interceptor will be able to intercept all calling conventions and
> all CPU configurations. So for example on x86_64, it can intercept
> both System V and MSabi, and also it can intercept SSE processors as
> well as AVX-512 processors (it checks at runtime to see what the CPU
> is capable of).
>
> Next I will code it for x86_32, and it will work for stdcall, cdecl,
> thiscall and so on. After that will be aarch64, followed by 32-Bit
> ARM.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
std-proposals_at_[hidden]> wrote:
> Consider intercepting a call to a function such as 'printf'. Instead
> of parsing all the percentage signs individually, you just want to
> forward all the arguments on. So the interceptor should be totally
> agnostic to the signature of the target function -- totally oblivious
> to its return type and parameter types.
https://wg21.link/p2826 seems better.
Like this:
>
> #include <cstdio> // printf
> #include <chrono> // seconds
> #include <thread> // sleep_for
>
> [[interceptor]] void MyInterceptor(void) noexcept
> {
> // Sleep for 1 second before jumping to 'printf'
>
> std::this_thread::sleep_for( std::chrono::seconds(1) );
> goto -> std::printf;
> }
>
> int main(int const argc, char **const argv)
> {
> auto const fp = (decltype(std::printf)*)&MyInterceptor;
>
> fp("My favourite number is %i,\nand my favourite word is %s.\n",
> argc,
> argv[ argc - 1 ]);
> }
>
> And well here it is now working up on GodBolt:
>
> https://godbolt.org/z/6qqTrq6Wj
>
> I want to explain to compiler vendors just how easy it is to implement
> this new feature. Here's what you do:
>
> Step 1 - When the compile encounters a function with the attribute
> [[interceptor]], create a second function declaration with the same
> name but prepended with "__core_", and change the second declaration's
> return type from 'void' to 'void(*)(void)'. Compile the body of the
> function into the second declaration. (The original declaration will
> become a thunk).
>
> Step 2 - Inside the body of the interceptor function, the 'return'
> statement should instead be written as 'goto ->'.
>
> Step 3 - Emit a thunk with the name of the original function
> declaration and give it assembler as follows:
>
> push_all_arguments
> call __core_Func
> pop_all_arguments
> jmp target_function
>
> It really is that simple. And because the original function name is
> mangled before "__core_" is prepended, it also works with templates:
>
> https://godbolt.org/z/8bYja9zfn
>
> In the above GodBolt, the original function name is mangled as
> "_Z13MyInterceptorILi0EEvv", and so then the core becomes
> "__core__Z13MyInterceptorILi0EEvv". You can have multiple template
> instantiations:
>
> https://godbolt.org/z/exxz5vcGo
>
> Easy peasy. Here's what I've got so far for the GNU compiler patch:
>
> https://github.com/healytpk/gcc-thomas-healy/commit/tag_interceptor
>
> It's not perfect but it's a really good proof of concept.
>
> Note that for any given target CPU instruction set, such as x86_64,
> the interceptor will be able to intercept all calling conventions and
> all CPU configurations. So for example on x86_64, it can intercept
> both System V and MSabi, and also it can intercept SSE processors as
> well as AVX-512 processors (it checks at runtime to see what the CPU
> is capable of).
>
> Next I will code it for x86_32, and it will work for stdcall, cdecl,
> thiscall and so on. After that will be aarch64, followed by 32-Bit
> ARM.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2026-04-28 06:36:17
