2013-07-04 4 views
1

Я хочу поменять местами две локальные переменные, используя xor algorithm, однако это не позволит мне изменить адрес переменных. Если я создаю указатели на переменные, это позволит, но можно ли это сделать без использования указателей?Изменение адреса локальной переменной

Я пытаюсь сделать это

Point a = Point(); 
Point b = Point(1,1); 

&a ^= &b; 
&b ^= &a; 
&a ^= &b; 

Это ближе всего я был в состоянии добраться до того, что я хочу сделать

Point a = Point(); 
Point b = Point(1,1); 

Point *a_ptr = &a; 
Point *b_ptr = &b; 

a_ptr = (Point *)(((unsigned long)a_ptr)^(unsigned long)b_ptr); 
b_ptr = (Point *)(((unsigned long)a_ptr)^(unsigned long)b_ptr); 
b_ptr = (Point *)(((unsigned long)a_ptr)^(unsigned long)b_ptr); 

// The pointers are switched, but this will not work 
&a = a_ptr; 
+0

Почему вы хотите обменять таким образом – aaronman

+0

@aaronman - Нет особых причин. Просто интересно, возможно ли это. –

+0

Вы просто не можете переназначить адрес переменной. Нет причин, по которым я это поддерживаю. – chris

ответ

-1

Переменные языка языка C не существуют во время выполнения, как переменные на языках более высокого уровня. Локальная переменная «a» означает компилятору «адрес кадра стека - 2» или что бы то ни было. Эта ссылка существует только во время компиляции и фиксируется декларацией. Во время выполнения сгенерированный код просто извлекается из жестко закодированного адреса. Поэтому превращение переменной в другое место с кодом пытается изменить то, что не существует.

+0

В современных компиляторах 'a' даже не фиксируется, как вы здесь описываете. Он может варьироваться в пределах функции. Например. перед свопом это может быть «a = регистр EAX, b = регистр EBX». После swap это будет 'a = регистр EBX, a = register EAX'. То есть обмен не перемещал значения на уровне сборки, и никаких инструкций не требовалось. Просто обновление бухгалтерии компиляторов. – MSalters

+0

Точно, и все, что происходит во время компиляции. –

+0

Просто, чтобы уточнить, комментарий был о части «исправлено с помощью декларации». Декларация больше не имеет к этому отношения. Теперь его распределение определяется присвоением (-ами). – MSalters

1

Единственный способ, которым можно было бы, если вы на самом деле сделали xor swap на значениях точки. В вашем коде кажется, что вы пытаетесь установить адрес значения в стек, который вы не можете сделать.

Что я рекомендую - std::swap.
http://en.cppreference.com/w/cpp/algorithm/swap.
Чтобы использовать это, ваш объект будет передан moveContructible и moveAssignable.

Так что коротко нет, именно то, что вы хотите сделать, невозможно, потому что вы не можете назначить адрес переменной. Но вы можете добиться аналогичного эффекта несколькими способами, используя значения точки, указатели или std::swap

Смежные вопросы