The behavior you're seeing likely comes down to how the compiler handles type-specific optimizations and inlining. Even though the logic for sorting pointers is identical, Clang might still generate separate code for each type due to subtle type differences like size or alignment, especially when inlining happens. Casting to void** erases the type info, allowing for a more generic version, which reduces the binary size. Despite aggressive optimization with -O3, the compiler may not deduplicate these instantiations. Link-time optimization (-flto) could help fold identical code across types, which might explain why you’re not seeing folding when inlining doesn't happen. This variation also shows how Clang handles templates differently than other compilers, leading to these size differences.