Минутка WTF-17: То ли лыжи
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.02.17 07:35
Оценка: 139 (7)
Всем привет.

Вообще, это из категории WTF, просто не хотел в заголовок эти буквы ставить.

Интересует, считаете ли вы такие изменения эквивалентными в отношении результата фукнции?

static byte[] BuildFileHeader() // до
{
    const ushort formatVersion = 1;
    var headerDwords = new []
    {
        0x0000ADDEu + (formatVersion << 16),
        0x00000000u
    };
    return headerDwords.SelectMany(BitConverter.GetBytes).ToArray();
}

static byte[] BuildFileHeader(ushort formatVersion = 1) // после
{
    var headerDwords = new[]
    {
        0x0000ADDEu + (formatVersion << 16),
        0x00000000u
    };
    return headerDwords.SelectMany(BitConverter.GetBytes).ToArray();
}
Отредактировано 24.02.2017 8:51 samius . Предыдущая версия . Еще …
Отредактировано 24.02.2017 8:48 samius . Предыдущая версия .
минутка wtf
Re: То ли лыжи не едут, то ли палки не идут
От: Sinix  
Дата: 24.02.17 08:36
Оценка:
Здравствуйте, samius, Вы писали:

S>Вообще, это из категории WTF, просто не хотел в заголовок эти буквы ставить.


Таки стоит. И тег навесить.

Чтоб не портить интригу — без комментариев пока.
Re: Минутка WTF-17: То ли лыжи
От: const_volatile  
Дата: 24.02.17 10:18
Оценка:
Здравствуйте, samius, Вы писали:

S>Интересует, считаете ли вы такие изменения эквивалентными в отношении результата фукнции?


S>
S>static byte[] BuildFileHeader() // до
S>{
S>    const ushort formatVersion = 1;
S>    var headerDwords = new []
S>    {
S>        0x0000ADDEu + (formatVersion << 16),
S>        0x00000000u
S>    };
S>    return headerDwords.SelectMany(BitConverter.GetBytes).ToArray();
S>}

S>static byte[] BuildFileHeader(ushort formatVersion = 1) // после
S>{
S>    var headerDwords = new[]
S>    {
S>        0x0000ADDEu + (formatVersion << 16),
S>        0x00000000u
S>    };
S>    return headerDwords.SelectMany(BitConverter.GetBytes).ToArray();
S>}
S>


подозреваю, что в первом случае тип массива headerDwords — uint[], а во втором long[]. integral promotion, все дела.
Re[2]: Минутка WTF-17: То ли лыжи
От: const_volatile  
Дата: 24.02.17 10:22
Оценка: 2 (1) +2
Здравствуйте, const_volatile, Вы писали:

S>>Интересует, считаете ли вы такие изменения эквивалентными в отношении результата фукнции?


кстати, именно поэтому я у себя стараюсь не использовать var для объявления целочисленных переменных. слишком велика вероятность, как в этом примере, ненароком прострелить себе ногу.
Re: Минутка WTF-17: То ли лыжи
От: StatujaLeha на правах ИМХО
Дата: 24.02.17 10:38
Оценка: 123 (6) +1
Здравствуйте, samius, Вы писали:

Если в первом варианте добавлять/убирать const у formatVersion, то эффект такой же.

А так круто, да.
В первом варианте компилер оптимизировал: просто сложил константы, увидел, что это все влезает в UInt32 -> тип массива выводим как UInt32[].

В втором случае просто сложить нельзя(потому что теперь работает с переменной). Нужен подход интеллектуальнее, но его нет.
Поэтому сделано по стандартным правилам(7.3.6.2 Binary numeric promotions):
1. (ushort << 16) -> ((int)ushort << 16) -> int//тупо кладем ushort как int
2. uint + int -> (long)uint + (long)int -> long
3. Int64[]
Re[2]: Минутка WTF-17: То ли лыжи
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.02.17 14:43
Оценка:
Здравствуйте, const_volatile, Вы писали:

_>Здравствуйте, samius, Вы писали:


_>подозреваю, что в первом случае тип массива headerDwords — uint[], а во втором long[]. integral promotion, все дела.

Интересно, почему в одном случае так, в другом — этак.
Re[2]: Минутка WTF-17: То ли лыжи
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.02.17 14:46
Оценка:
Здравствуйте, StatujaLeha, Вы писали:

SL>Здравствуйте, samius, Вы писали:


SL>Если в первом варианте добавлять/убирать const у formatVersion, то эффект такой же.

Есть еще как минимум один способ получить эффект, даже не убирая const. Ввести константу ushort со старшим битом.

SL>А так круто, да.

SL>В первом варианте компилер оптимизировал: просто сложил константы, увидел, что это все влезает в UInt32 -> тип массива выводим как UInt32[].

SL>В втором случае просто сложить нельзя(потому что теперь работает с переменной). Нужен подход интеллектуальнее, но его нет.

SL>Поэтому сделано по стандартным правилам(7.3.6.2 Binary numeric promotions):
SL>1. (ushort << 16) -> ((int)ushort << 16) -> int//тупо кладем ushort как int
SL>2. uint + int -> (long)uint + (long)int -> long
SL>3. Int64[]

Вот, вообще удивительно то, что тип выражения зависит от того, что там интеллектуальный компилятор увидел, а не от того, что написано в Binary numeric promotions.
Re[3]: Минутка WTF-17: То ли лыжи
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.02.17 14:48
Оценка: 21 (1)
Здравствуйте, const_volatile, Вы писали:

_>Здравствуйте, const_volatile, Вы писали:


S>>>Интересует, считаете ли вы такие изменения эквивалентными в отношении результата фукнции?


_>кстати, именно поэтому я у себя стараюсь не использовать var для объявления целочисленных переменных. слишком велика вероятность, как в этом примере, ненароком прострелить себе ногу.

Все правильно.
Но что бы не стрелять в ноги у нас есть тесты. Теперь, конечно, пришлось задать тип массиво явно и попросить решарпер подзаткнуться с предложениями опустить его.
Я даже думаю что тип массива изначально был, но из-за подсказки решарпера и был убран.
Re: Минутка WTF-17: То ли лыжи
От: NetDeveloper  
Дата: 24.02.17 17:29
Оценка:
В первом случае кладется конкретное значение константы в стэк, во втором случае значение аргумента со стэка, код будет разный.
Отредактировано 24.02.2017 17:30 NetDeveloper . Предыдущая версия .
Re[4]: Минутка WTF-17: То ли лыжи
От: Sinix  
Дата: 24.02.17 17:39
Оценка: 5 (2) +1
Здравствуйте, samius, Вы писали:

S>Я даже думаю что тип массива изначально был, но из-за подсказки решарпера и был убран.


О, пока не было, всё уже ответили

По теме, раз: очередной довод за "var для примитивных типов? Приятной отладки.".

Но тут надо сказать, что у меня _очень_ предвзятая позиция, т.к. регулярно приходится разгребать последствия "чо там думать, решарпер подсказал => так и надо".
Если такого опыта нет, то да — код с var читается гораздо проще. Не, он может быть некорректным, но читается-то проще


По теме, два: было бы классно иметь предупреждение "result expression is wider than operand types", или предупреждением решарпера, или анализатором рослина.
ErrorProne.Net от ув. SergeyT заброшен, закину ради интереса в форум JetBrains.
Re[5]: Минутка WTF-17: То ли лыжи
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.02.17 18:58
Оценка: 29 (3) +1
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, samius, Вы писали:


S>По теме, раз: очередной довод за "var для примитивных типов? Приятной отладки.".

var для встроенных отключен. Но массив встроенных — уже не встроенный, так что решарпер не обманул, но подвел. То есть, либо включать все explicit, либо он будет предлагать массив встроенных обваривать и будет по-своему прав (в рамках возможности задания настроек).

S>Но тут надо сказать, что у меня _очень_ предвзятая позиция, т.к. регулярно приходится разгребать последствия "чо там думать, решарпер подсказал => так и надо".

S>Если такого опыта нет, то да — код с var читается гораздо проще. Не, он может быть некорректным, но читается-то проще

В данном случае, если у мменя претензии и есть, то вовсе не к решарперу. Проблема не в var-е, а в том, что var-ы ввели в язык, у которого
1) куча неявных приведений типа с удивительной возможностью определять свои операторы неявного приведения. Кстати, не по теме (если я их определяю, то что бы повесить на него [Obsolete("", true)]).

2) Unary + Binary numeric promotions, которые надо по-хорошему знать на зубок. Но многие программисты в C# набегами. Чего уж там, я сам не каждый год открываю спецификацию языка, хотя на C# с первой беты (был лишь года два перерыв). Они, кстати, тут заметной роли в смене типа массива не сыграли.

3) По теме. Кто-нибудь может объяснить, с какого перепугу тип выражения зависит от того, const ему подали или нет? А так же, как тип выражения оказался зависим от значения, которое присутствует в выражении? Я понимаю, что об этом можно почитать в 4.1.5 Integral types, но это же бред. Когда просто читаешь этот раздел — ну там просто "нормальному" человеку в голову не придет что вводится зависимость от const и значения величины. А когда напарываешься, понимаешь, что вроде явно не противоречит. И возможно, это еще не все сюрпризы.

S>По теме, два: было бы классно иметь предупреждение "result expression is wider than operand types", или предупреждением решарпера, или анализатором рослина.

S>ErrorProne.Net от ув. SergeyT заброшен, закину ради интереса в форум JetBrains.
Не возражаю.
Я бы порекомендовал JB немного расширить настройки и ввести в них правило для var-ов в выражениях (наравне со встроенными типами), где используются ЛЮБЫЕ неявные преобразования. От implicit преобразований до promotions и integral types. Интересует настройка, которая не будет просить вкорячивать туда var.

А автору 4.1.5 и тем, кто это одобрил — воздерживаться. И я не предлагаю делать что-нибудь по этому поводу с языком. var-ы уже не выкинешь, а 4.1.5 тем более.
Re[6]: Минутка WTF-17: То ли лыжи
От: _NN_ www.nemerleweb.com
Дата: 25.02.17 19:04
Оценка:
Здравствуйте, samius, Вы писали:

S>Я бы порекомендовал JB немного расширить настройки и ввести в них правило для var-ов в выражениях (наравне со встроенными типами), где используются ЛЮБЫЕ неявные преобразования. От implicit преобразований до promotions и integral types. Интересует настройка, которая не будет просить вкорячивать туда var.


Давай ссылку на просьбу в youtrack, мы поддержим
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Минутка WTF-17: То ли лыжи
От: WolfHound  
Дата: 25.02.17 20:37
Оценка: :)
Здравствуйте, StatujaLeha, Вы писали:

SL>Если в первом варианте добавлять/убирать const у formatVersion, то эффект такой же.

SL>А так круто, да.
SL>В первом варианте компилер оптимизировал: просто сложил константы, увидел, что это все влезает в UInt32 -> тип массива выводим как UInt32[].
Засунуть оптимизатор в типизатор... у меня нет цензурных слов.
Кого микрософт вообще нанимает для дизайна C#?
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.