ИЗМЕНИТЬ Предупреждение об общественном здравоохранении. Этот вопрос содержит ложное предположение о неопределенном поведении. Смотрите принятый ответ.
Прочитав недавнюю запись в блоге, я много думал о практичности отказа от всех стандартов. -неопределенные предположения в коде C и C++. Вот фрагмент, вырезанный из С++, чтобы сделать беззнаковое 128-битное добавление...
void c_UInt64_Pair::operator+= (const c_UInt64_Pair &p)
{
m_Low += p.m_Low;
m_High += p.m_High;
if (m_Low < p.m_Low) m_High++;
}
Это явно зависит от предположений о поведении переполнения. Очевидно, что большинство машин могут поддерживать двоичное целое число правильного типа (хотя, возможно, построение из 32-битных фрагментов или чего-то еще), но, по-видимому, растет вероятность того, что оптимизатор может использовать здесь стандартное неопределенное поведение. То есть единственный способ, которым может быть выполнено условие m_Low < p.m_Low
, — это переполнение m_Low += p.m_Low
, что является неопределенным поведением, поэтому оптимизатор может на законных основаниях решить, что условие всегда не выполняется. В этом случае этот код просто сломан.
Поэтому вопрос...
Как вы можете написать достаточно эффективную версию вышеизложенного, не полагаясь на неопределенное поведение?
Предположим, что у вас есть подходящее 64-битное двоичное машинное число, но у вас есть вредоносный компилятор, который всегда будет интерпретировать ваше неопределенное поведение наихудшим из возможных (или невозможных) способов. Кроме того, предположим, что у вас нет какой-то специальной встроенной, встроенной библиотеки или чего-то еще, что могло бы сделать это за вас.
ИЗМЕНИТЬ небольшое уточнение. Речь идет не только об обнаружении переполнения, но и о том, что и m_Low, и m_High в конечном итоге дают правильные результаты по модулю 2^64, что также не определено стандартами.
'a'
, например: разные ответы в C и C++. - person David Thornley   schedule 25.08.2010