Is it possible to use metaprogramming tricks to allow SFINAE on assembly blocks? For example to detect if an instruction like "CPUID" is available on a processor: (this is not valid code, but illustrates what I would like to achieve)
// This should work if `CPUID` is a valid instruction on the target architecture
template <
class... T,
class = decltype(sizeof...(T), asm volatile("CPUID":::)
>
bool f(T...) {
return true;
}
// This should fail because `BLAH` is not an instruction
template <
class... T,
class = decltype(sizeof...(T), asm volatile("BLAH":::)
>
bool f(T...) {
return true;
}
Substitution failure is not an error (SFINAE) refers to a situation in C++ where an invalid substitution of template parameters is not in itself an error. David Vandevoorde first introduced the acronym SFINAE to describe related programming techniques.
So the simple answer is YES.
It is impossible to achieve what is formulated in the question the way it is formulated for multiple reasons listed below. However, by generalizing the idea it may become something that might be making sense to include into some future revision of the language.
The reasons why it will not work:
asm
blocks are opaque to the C++ compiler. The syntax of such blocks is compiler-specific. I do not think that MS VC++ accepts clobber lists the way it is supported by GCC and Intel compiler. Moreover, Microsoft's x86_64 compilers stopped supporting assembly blocks as they force people to use intrinsics. By the way, maybe relying on presence of intrinsic functions can be used to offer a compile-time CPU dispatching instead? Could be worth exploring this idea.
asm
blocks are target architecture-specific. There are other ways to detect the target architecture at compile-time.
The very notion of an instruction being present/absent is very vague. Which entity is authorized to make a decision on any given asm
expression: the assembler program that translates its text into machine code or the target processor itself that runs the actual code? Both choices are problematic.
As it is, there is no way to know the outcome of an opaque block without executing it first. So, the compiler may want to call an arbitrary program to return a value which then will be used for template expansion. Such a program can then do processor- or instruction-sensing and return its findings to guide compilation further.
Now this looks abstract enough to be a language feature, as we dictate no assumptions on the nature of such an external program. There are still portability (+ cross-compiling) issues and security (running an external program is risky) issues. All in all, it looks better to me to rely on existing macrodefinitions coming into compiler from the environment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With