РЕДАКТИРОВАТЬ Предупреждение общественного здравоохранения - этот вопрос содержит ложное предположение о неопределенном поведении.См. Принятый ответ.
После прочтения недавнего сообщения в блоге я много размышлял о целесообразности избегания всех неопределенных в стандартах допущений в коде C и 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, что также не определено стандартами.