Похоже, что компиляторы просто недостаточно умны, чтобы рассматривать встраивание как особый случай. Они генерируют тот же код, что и в случае, когда функция имеет внешнюю связь, и в этом случае связь между параметрами c0 и c1 не предполагается.
Внутри функции c0
и c1
находятся в локальных копиях в соответствии с соглашением о вызовах ABI, которое не обязательно размещает их рядом друг с другом для выравниваемого доступа - даже если это действительно case в вашем конкретном примере c x86.
Изменение кода вызывающего абонента на alignas(int) char str[2] = {'0', 'x'}; return beginswith(str[0],str[1],s);
не имеет значения, поэтому выравнивание также не является (единственной) причиной.
Однако, если вы измените функцию следующим образом:
inline bool beginswith (char c0, char c1, const char* s)
{
char tmp[2] = {c0, c1};
return memcmp(tmp, s, 2);
}
Тогда вы получите идентичный машинный код в обоих случаях ( godbolt ].
test(char const*):
cmp WORD PTR [rdi], 30768
setne al
ret
Следует отметить, что *(const short*)s
в test2
- неопределенное поведение, строгое нарушение псевдонимов. Машинный код для этой строки может не оставаться детерминированным c, когда программа начинает масштабироваться или когда настройки оптимизатора Это в основном качество реализации, где стандарт не дает никаких гарантий и test2
может сломаться в любой момент.