В чем разница между (a!= B) и (a!= (A = b)?
В недавнем вопросе мы нашли следующий фрагмент кода:
// p, t, q and tail are Node<E> objects.
p = (p != t && t != (t = tail)) ? t : q;
Опуская контекст вопроса, меня интересует следующее поведение:
t != (t = tail)
Учитывая, что это объекты одного типа, независимо от типа. Есть ли разница между этим и:
t != tail
Или я упускаю что-то решающее в механизме сравнения?
РЕДАКТИРОВАТЬ
Если кому-то интересно, это можно найти в классе ConcurrentLinkedQueue из java.util
линия 352.
3 ответа
t != (t = tail)
эквивалентно
oldt = t;
t = tail;
... oldt != t...
т.е. первоначальная стоимость t
по сравнению с tail
и кроме того t
присваивается значение tail
,
Это короткий способ написания
if (t != tail) {
t = tail;
}
Первый код:
t != (t = tail)
назначит хвост t, затем сравнит t с новым значением
второй будет сравнивать т с хвостом
Примечание: другой ответ - то, что фактически делает Java
synchronized(x) {
if(t != (t = tail));
}
эквивалентно
synchronized(x) {
t = tail;
if(t != t) {
// ...
}
}
в основном, ссылка на то, что назначено, возвращается оператором ()
public class Test {
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
if(a != (b = a)) {
System.out.println("however, there is an issue with a != (a = b), Java bug");
} else {
System.out.println("assignment first, obvious by inspection");
}
}
}
Тем не менее, тот же код работает в Си. Если я должен был догадаться, это непреднамеренно в Java, любое отклонение от C на что-то вроде этого глупо. Oracle, вероятно, не собирается отказываться от него, предполагая, что это непреднамеренная ошибка, что, вероятно, и есть.
Я доберусь до этого в следующий раз, когда поговорю с ними. Я до сих пор злюсь на них из-за того фиаско Обители в Министерстве обороны США, связанное с созданием домашней страницы моей мамы ask.com в сговоре с Apple Incorporated. Apple исправила iTunes менее чем через неделю после того, как мне пришлось нажимать на эту вещь более 400 раз, чтобы повторить попытку после повторной загрузки сбоев видео библиотеки моей дочери, поэтому проблема ограничена Oracle. Это также повлияло на Microsoft, поэтому все были без ума от этого.
#include <iostream>
static int ref = 0;
class t {
public:
t(int x) : x(x), r(ref) { ref++; }
t(const t& o) : x(o.x), r(o.r) { }
t& operator=(const t& o) { x = o.x; r = o.r; return *this; }
bool operator!=(const t& o) const { return r != o.r; }
private:
int x;
int r;
};
int main() {
t a(1);
t b(2);
if(a != (a = b)) {
std::cout << "assignment\n";
} else {
std::cout << "no assignment\n";
}
return 0;
}