Здравствуйте, ksg71, Вы писали:
K>Здравствуйте, _NN_, Вы писали:
_NN>>Здравствуйте, ksg71, Вы писали:
K>>>заверни в try catch и все будет _NN>>Вопрос не об этом.
K>а в чем?
О том, что компилятор не создаёт временный объект в релизе, хотя в спецификации написано, что создаёт.
Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, ksg71, Вы писали:
K>>Здравствуйте, _NN_, Вы писали:
_NN>>>Здравствуйте, ksg71, Вы писали:
K>>>>заверни в try catch и все будет _NN>>>Вопрос не об этом.
K>>а в чем?
_NN>О том, что компилятор не создаёт временный объект в релизе, хотя в спецификации написано, что создаёт.
_NN>https://github.com/dotnet/csharplang/blob/master/spec/expressions.md#object-initializers
_NN>An instance of Point can be created and initialized as follows: _NN>
_NN>Point a = new Point { X = 0, Y = 1 };
_NN>
_NN>which has the same effect as _NN>
_NN>Point __a = new Point();
_NN>__a.X = 0;
_NN>__a.Y = 1;
_NN>Point a = __a;
_NN>
Здравствуйте, _NN_, Вы писали:
_NN>Всегда думал, что код _NN>
_NN> a q = new a(1) {
_NN> x = 1,
_NN> y = 2,
_NN> };
_NN>
_NN>идентичен
_NN>
_NN> a tempq = new a(1);
_NN> tempq.x = 1;
_NN> tempq.y = 2;
_NN> a q = tempq;
_NN>
_NN>Однако при компиляции в релиз это не так.
_NN>Это так было всегда ?
Похоже сейчас компилятор пытается это оптимизировать, и создает временный объект, только если в коде есть верояность обращения к недоинициализированному объекту. Пример
Здравствуйте, sergeya, Вы писали:
S>Похоже сейчас компилятор пытается это оптимизировать, и создает временный объект, только если в коде есть верояность обращения к недоинициализированному объекту.
Разве не пофиг, кто именно окажется "недоинициализированным" — временный объект или главный?? Иксепшн по-любому прерывает нормальный ход инициализации и ты не можешь пользоваться таким объектом.
Так что "временная переменная" как бы нафиг не нужна.
Здравствуйте, _NN_, Вы писали:
_NN>О том, что компилятор не создаёт временный объект в релизе, хотя в спецификации написано, что создаёт.
_NN>which has the same effect as
В данном случае "тот же эффект" может быть попросту примером псевдокода. Т.е. для наглядности разложили присвоение на две части и расписали правую как "сложную конструкцию", выходом которой есть временный объект. В коде его генерировать не обязательно.
Здравствуйте, JohnnyJ, Вы писали:
JJ>Здравствуйте, _NN_, Вы писали:
_NN>>О том, что компилятор не создаёт временный объект в релизе, хотя в спецификации написано, что создаёт.
JJ>а есть принципиальная разница в наличии или отсутствии этой временной переменной?
Есть небольшая разница .
Например у меня есть структура размером в несколько килобайт для работы с нативным кодом.
Метод вызывается часто.
С этой оптимизацией не нужно переживать за лишние копирования.
Здравствуйте, Kolesiki, Вы писали:
K>Здравствуйте, sergeya, Вы писали:
S>>Похоже сейчас компилятор пытается это оптимизировать, и создает временный объект, только если в коде есть верояность обращения к недоинициализированному объекту.
K>Разве не пофиг, кто именно окажется "недоинициализированным" — временный объект или главный?? Иксепшн по-любому прерывает нормальный ход инициализации и ты не можешь пользоваться таким объектом. K>Так что "временная переменная" как бы нафиг не нужна.
Временный недоступен за пределами блока try. Посмотри пример, который я выложил в первом сообщении.
public class C {
public void M() {
a a = null;
try {
a = new a(1) {
x = 1,
y = 2,
};
} catch {
a.ToString(); // если закомментировать эту строчку, то компилятор выкинет создание временного объекта
}
}
}
Здравствуйте, sergeya, Вы писали:
S>Похоже сейчас компилятор пытается это оптимизировать, и создает временный объект, только если в коде есть вероятность обращения к недоинициализированному объекту.
Можно даже без try-catch.
Достаточно объявить поле класса или ref/out аргумент.
_NN> a tempq = new a(1);
_NN> tempq.x = 1;
_NN> tempq.y = 2;
_NN> a q = tempq;
_NN>
_NN>Однако при компиляции в релиз это не так.
При компиляции всё то же самое, просто отсутствует последняя строка: a q = tempq, потому что нафиг не нужна. А что временная локальная переменная, с которой происходят операции, называется "q", а не "temp" или как-то по-другому, это роли не играет. Локальные переменные вообще штуки эфемерные. Могут существовать или не существовать независимо от того, что ты наобъявлял в своём коде; их имена ни на что не влияют и через рефлексию недоступны.
Если финальная переменная не локальная, а какое-нибудь доступное извне поле
public static A a;
public void M()
{
a = new A(1)
{
x = 1,
y = 2,
};
}
то после компиляции получается ожидаемо
public static A a;
public void M()
{
A obj = new A(1);
obj.x = 1;
obj.y = 2;
a = obj;
}