У меня есть особая проблема, которая возникает как в VS2005, так и в 2010 году. У меня есть цикл for, в котором вызывается встроенная функция, в сущности что-то вроде этого (C ++, только для иллюстративных целей):
inline double f(int a)
{
if (a > 100)
{
// This is an error condition that shouldn't happen..
}
// Do something with a and return a double
}
И затем цикл в другой функции:
for (int i = 0; i < 11; ++i)
{
double b = f(i * 10);
}
Теперь происходит то, что в отладочной сборке все работает нормально.В сборке релиза со всеми включенными оптимизациями это, согласно разборке, скомпилировано так, что i
используется напрямую без * 10
, а сравнение a > 100
превращается в a > 9
, в то время как я предполагаю, что это должно быть a > 10
.Есть ли у вас какие-либо сведения о том, что может заставить компилятор думать, что a > 9
- правильный путь?Интересно, что даже незначительное изменение (например, распечатка отладки) в окружающем коде заставляет компилятор использовать i * 10
и сравнивать его с буквальным значением 100.
Я знаю, что это несколько расплывчато, но я 'Буду благодарен за любую старую идею.
РЕДАКТИРОВАТЬ:
Вот, мы надеемся, воспроизводимый случай.Я не считаю его слишком большим, чтобы его можно было вставить здесь, так что вот так:
__forceinline int get(int i)
{
if (i > 600)
__asm int 3;
return i * 2;
}
int main()
{
for (int i = 0; i < 38; ++i)
{
int j = (i < 4) ? 0 : get(i * 16);
}
return 0;
}
Я проверил это с VS2010 на своей машине, и, похоже, он ведет себя так же плохо, как и исходный код, который у меня естьпроблемы с.Я скомпилировал и запустил это с пустым шаблоном проекта C ++ IDE по умолчанию в конфигурации выпуска.Как видите, разрыв никогда не должен быть достигнут (37 * 16 = 592).Обратите внимание, что удаление i < 4
делает эту работу, как и в оригинальном коде.