GCC 4.5.2 (на Ubuntu 11.10 x64, но компиляция для 32 бит) генерирует неверный код сборки, и мне любопытно, можно ли исправить ошибку без изменения кода, просто применив параметры или что-то вроде что. Обратите внимание, что оптимизация уже -O0.Ошибка генерации кода сборки GCC
У меня есть две функции:
inline long Class::Get()
{
long v = *(long*)(m_p);
m_p += 4;
return v;
}
inline void Class::Command()
{
m_p += Get();
}
GCC 4.5.2 генерирует этот сборочный код:
9840 m_p += Get();
f689eff5: mov 0x8(%ebp),%eax
f689eff8: mov 0xd4(%eax),%eax
f689effe: mov %eax,%esi
f689f000: mov 0x8(%ebp),%eax
f689f003: mov %eax,(%esp)
f689f006: call 0xf66116a0
f689f00b: lea (%esi,%eax,1),%edx
f689f00e: mov 0x8(%ebp),%eax
f689f011: mov %edx,0xd4(%eax)
Как вы можете видеть, что сохраняет m_p значение в% ЭСИ, а затем добавляет возвращаемое значение к нему используя lea. BUT :: Get() также меняет m_p! о котором GCC, похоже, не знает. Таким образом, ошибка, m_p неверна (на 4 байта меньше ожидаемой), потому что значение в% esi устарело.
я могу это исправить с помощью
inline void Class::Command()
{
long v = Get();
m_p += v;
}
Но мне просто интересно, если я могу применить некоторые прагму или то вроде этого, без изменения кода, чтобы сделать ошибку уйти. Что касается gcc-версии, я застрял в заданной.
Вы не получаете предупреждение о 'long v = * (long *) (m_p);'? Я считаю, что это тип punning и технически UB? Может быть, попробуйте '-fno-strict-aliasing', если вы собираетесь писать небезопасный код вроде этого? –
вы всегда можете отличить ... –
Нет, предупреждения отключены. Но я не вижу, как это связано. И я не пишу такой код, я просто работаю с ним. – queen3