Как компилятор обрабатывает автоматическую переменную, когда в присваивании участвуют двоичные операции - PullRequest
0 голосов
/ 09 января 2019

Я хотел бы знать, обрабатывает ли Compile (или язык) различные переменные, например:

auto unsigned int a;
a = 8;

от

auto unsigned int a;
a = 1 << 3;

Точнее, здесь a = 8 в месте a будет записано значение 8, поэтому не важно, какое значение было (даже если есть мусор).

Я не уверен, как именно это работает в этой ситуации a = 1 << 3.

Я уверен, что внутри a есть значение мусора, и если, например, a == 1341 (значение мусора), то a = 1 << 3 приведет к 8.

Но если 1341 в двоичном представлении означает:

00000101 00111101

тогда я ожидал быть 10728:

00101001 11101000.

Что я не совсем уверен, так это то, что a рассматривается как 00000000?

В этой форме a инициализируется до 0 до выполнения операции слева?

Что-то вроде 00000000 = 1 << 3?

Где a становится 0000 1000, или как на самом деле работает в этой ситуации?

Я понимаю, что unsigned int a = 0, тогда a = a << 3 будет 8 = 0000 1000, но это отличается от моего Вопроса, потому что здесь a << операции на a, а не на 1, как в моем Вопрос.

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Давайте пошагово перейдем к выражению a = 1<<3

  1. Это простой оператор присваивания, в котором lvalue должен быть оценен. Таким образом, 1 << 3 будет оценено как 8. Так как 1 и 3 являются целочисленными литералами, и компилятор может сгенерировать инструкцию по сборке, наподобие ROL 1,3 -> Повернуть 1 влево на 8 и сохранить результат в накопителе.

    << имеет более высокий прецедент, чем =.

  2. До сих пор мы не знаем, где нам нужно хранить результат предыдущего шага. Поскольку a компилятор авто переменных может решить сохранить его в сегменте stack. Псевдо инструкция может быть MOV @SP+4, A -> Переместить данные аккумулятора в локацию указывается указателем стека со смещением 4.

Как вы правильно сказали, a изначально будет иметь значение мусора. Но это не влияет на второе утверждение.

P.S .: Все инструкции по сборке будут привязаны к платформе. Вышеуказанные шаги приведены только для примера.

EDIT

Как указывает Лундин 1<<3 является целочисленным константным выражением, поэтому оно будет вычислять время компиляции. Таким образом, мы можем получить один шаг времени выполнения, который будет копировать 8 в стек.

0 голосов
/ 09 января 2019
auto unsigned int a; //a is garbage value yet
a = 1 << 8; // a assign 1<<8(256) to a. a will be 1 << 8.

если вы хотите установить 8-ую битовую маску, то вам должно понравиться это:

a |= (1 << 8); //not assign, just set bitmask.

затем работает так, как вы ожидаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...