Ответ на вопрос о практическом интервью

Я просто переживаю кучу интервью с С++, чтобы убедиться, что нет ничего очевидного, что я не знаю. До сих пор я не нашел ничего, что я уже не знал, кроме этого:

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 бит сохраняются, остальные обнуляются