The more I've written code close to metal (mostly SIMD for signal processing), the more I've grown to prefer either intrinsics or separate translation unit for assembly.
If you want your code to intertwine with what the C compiler does, intrinsics are great.
Yes, and the set of intrinsics supported by MSVC is really lacking. On x64, this left no way to force a conditional move to bypass a poorly predictable branch, nor was there a way to access carry-extended operations until recently. On ARM64, it doesn't have complete coverage of scalar intrinsics for operations like RBIT (reverse bit order).
I’m not a fan of concatenating strings either. I was thinking about the MSVC/Pascal-style inline assembly here, which isn’t based on strings.
Correct me if I’m wrong, but I don’t think that you can guarantee a routine is constant-time by using intrinsics. You need asm for that. Asm that won’t be changed by the compiler. So you need to write an external asm file for that now, which is fair enough, but I just wouldn’t present intrinsics as all-around superior.
If you want your code to intertwine with what the C compiler does, intrinsics are great.
If you don't, .s is great.