Ответ на вопрос о практическом интервью
Я просто переживаю кучу интервью с С++, чтобы убедиться, что нет ничего очевидного, что я не знаю. До сих пор я не нашел ничего, что я уже не знал, кроме этого:
long value;
//some stuff
value &= 0xFFFF;
Вопрос: "Что не так с этим кодом?" И намекает, что это что-то связано с целевыми архитектурами.
Если ответ не просто "значение не инициализировано", я не вижу никакой проблемы. Насколько я могу судить, он просто маскирует 2 младших значащих байта значения, а long
гарантированно составляет не менее 2 байтов, поэтому проблем там нет.
Возможно, возможно, что long
может быть только 2 байта в целевой архитектуре, и вы можете потерять бит знака? Или возможно, что 0xFFFF - это int
и int
- всего 2 байта?
Спасибо заранее.
Ответы
Ответ 1
Эта проблема с этим кодом заключается в том, что он выполняет побитную операцию с подписанным значением. Результаты таких операций с отрицательными значениями сильно различаются для разных целых представлений.
Например, рассмотрим следующую программу:
#include <iostream>
int main(void)
{
long value;
value = -1; // Some stuff
value &= 0xffff;
std::cout << "Value = " << value << std::endl;
}
В архитектуре с двумя дополнениями результат:
Value = 65535
В архитектуре с одним дополнением результат:
Value = 65534
В архитектуре знака и величины результат:
Value = 1
Ответ 2
Трудно понять, что ожидал от вас интервьюер. Мы вроде как только должны угадать.
Я предполагаю, что на некоторых архитектурах 0xFFFF будет знаковым 16-битным значением, а long - знаковым 32-битным значением. Когда вы расширяете константу так, чтобы ее можно было использовать для маскирования длинного значения, она будет расширена и станет 0xFFFFFFFFl, что совсем не то, что вы намеревались.
Приложение: Код, написанный правильно, работает во всех трех компиляторах, которые я использую в настоящее время,
так что это действительно угадающая игра, пытаясь понять, что задумал интервьюер. Соответствующий стандартным 16-битным компилятором также будет генерировать правильный код, поэтому нам остается угадать, есть ли что-то, что мы пропустили, независимо от того, действительно ли этот пример не был нарушен, или когда интервьюер использовал 16-битный компилятор, который обрабатывал бы 0xFFFF как подписанное количество, когда вынуждено продлить его до длинного. Было бы интересно спросить его.
Ответ 3
Могу ли я сказать, что в этом коде нет ничего плохого, если не известен контекст или намерение окружающего кода!
Ответ 4
Это может быть выстрел в темноте, но при условии, что длинный vs int не является проблемой (другие ответили на него как ответ) и что 0xFFFF
охватывает всю сумму, требуемую типом, не будет это просто сделать value = 0xFFFF
, и нет необходимости в манипулировании бит? Не избыточно ли манипуляция бит?
Единственное, что я могу видеть, это то, что человек, задающий вопрос, хотел, чтобы вы поняли, что недостающие данные, содержащиеся в long, не будут затронуты, просто используя 0xFFFF.
Мне приходит в голову немного странно задавать вопрос, основываясь на том, как здесь задается вопрос, или, может быть, это настолько очевидно, что мы все это думаем:)
Ответ 5
Я подозреваю, что мы все слишком много думаем.
Что не так с этим кодом, это то, что значение не инициализируется. Вопрос в том, понимаете ли вы, что & = (или + =, - =/= и т.д.) Не имеет смысла при использовании на унифицированном значении?
Если значение инициализировано, поведение корректно определено. Наименее значимые 16 бит сохраняются, остальные обнуляются
Ответ 6
звучит как Big-Endian против Little-Endian для меня.
http://en.wikipedia.org/wiki/Endianness