Здравствуйте, AndrewVK, Вы писали:
AVK>С точки зрения безопасности — не лишние. Старые данные все равно нало почистить до передачи управления прикладному коду, иначе этот прикладной код может их прочесть.
Какая такая передача управления прикладному коду происходит в момент, когда выполняется int[] a = new int[10] ?
Ты путаешь обнуление страниц памяти перед передачей их другому процессу (это делает Windows) и обнуление полей структуры, размещенной в своем собственном стеке по правилам C# (или .net) . Даже если стек при этом растет и ему передаются новые страницы, Windows из обнулит сама. А структуру обнуляют совсем по другим причинам. Стек же, кто его знает, что там раньше было.
Впрочем, в С++ не обнуляют, этим должен заняться код программиста, если он не хочет там мусор иметь. Вполне возможно, что и он и не будет обнулять, если, скажем, потом a[i] = b[i] +c[i] — зачем a[i] обнулять-то ?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Какая такая передача управления прикладному коду происходит в момент, когда выполняется int[] a = new int[10] ?
Сейчас — никакой. А вот есть там кастомный дефолтный конструктор будет, то все не так однозначно.
PD>Ты путаешь обнуление страниц памяти перед передачей их другому процессу (это делает Windows) и обнуление полей структуры, размещенной в своем собственном стеке по правилам C# (или .net).
Я ничего не путаю. В CLR разные сборки могут иметь разные права доступа. В пределах одного процесса и даже домена.
PD>Впрочем, в С++ не обнуляют, этим должен заняться код программиста, если он не хочет там мусор иметь.
И в результате имеем непрерывный поток уязвимостей.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Какая такая передача управления прикладному коду происходит в момент, когда выполняется int[] a = new int[10] ?
AVK>Сейчас — никакой. А вот есть там кастомный дефолтный конструктор будет, то все не так однозначно.
А все же можно поподробнее, какая именно передача управления прикладному коду происходит в момент вызова конструктора ? Какой код до этого выполнялся — системный, что ли ? Вроде как нет, так как до этого стояло x = y, например. И почему при вызове кастомного конструктора с параметрами все по-прежнему однозначно, и никаких проблем нет, а вот если без параметров — неоднозначно ?
PD>>Ты путаешь обнуление страниц памяти перед передачей их другому процессу (это делает Windows) и обнуление полей структуры, размещенной в своем собственном стеке по правилам C# (или .net).
AVK>Я ничего не путаю. В CLR разные сборки могут иметь разные права доступа. В пределах одного процесса и даже домена.
А, вот ты о чем. Тут да,согласен, в дотнете надо обнулять еще и по этой причине. Разграничили доступ по стеку — контролируйте его теперь.
PD>>Впрочем, в С++ не обнуляют, этим должен заняться код программиста, если он не хочет там мусор иметь.
AVK>И в результате имеем непрерывный поток уязвимостей.
На которых работает Windows, Linux, да и сам дотнет, как впрочем, и сотни других программ.
Здравствуйте, Pavel Dvorkin, Вы писали:
AVK>>Сейчас — никакой. А вот есть там кастомный дефолтный конструктор будет, то все не так однозначно. PD>А все же можно поподробнее, какая именно передача управления прикладному коду происходит в момент вызова конструктора ?
Конструктор ведь может прочесть собственные поля, верно? И что за данные там будут, если их предварительно не потереть?
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
PD>>А все же можно поподробнее, какая именно передача управления прикладному коду происходит в момент вызова конструктора ?
AVK>Конструктор ведь может прочесть собственные поля, верно? И что за данные там будут, если их предварительно не потереть?
Потереть — я уже согласился. Я спрашиваю о том, что за передача управления прикладному коду происходит ? Из какого кода она происходит ?
Ну а что касается конструктора по умолчанию, то
//////////////////
Некоторые языки, как например, «голый» IL или Managed C++, поддерживают полноценные пользовательские конструкторы по умолчанию для значимых типов, которые позволяют инициализировать состояние структуры произвольным образом, а не только значениями по умолчанию.
////////////////// https://habrahabr.ru/post/152118/
Так что дело тут не в глубокой философии, в дотнете это ничему не противоречит. Причина где-то в C#.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Так что дело тут не в глубокой философии, в дотнете это ничему не противоречит. Причина где-то в C#.
Одной из главных причин отсутствия пользовательских конструкторов по умолчанию для структур заключается в падении производительности при работе с массивами.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
PD>>Так что дело тут не в глубокой философии, в дотнете это ничему не противоречит. Причина где-то в C#.
AVK>
AVK>Одной из главных причин отсутствия пользовательских конструкторов по умолчанию для структур заключается в падении производительности при работе с массивами.
Это я помню. Правда, так и остается неясным, почему в MC++ и IL этого падения нет. Уж в MC++ об этом должны были в первую очередь позаботиться — если в нем было что-то полезное на момент его создания, то это эффективность кода по сравнению с тогдашним С#. Впрочем, может, и с нынешним.
На вопрос же насчет передачи управления пользовательскому коду, я так понимаю, ответа не будет ?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Это я помню. Правда, так и остается неясным, почему в MC++ и IL этого падения нет.
Оно там тоже есть. Но высокий уровень совместимости с С++ важнее.
PD>На вопрос же насчет передачи управления пользовательскому коду, я так понимаю, ответа не будет ?
Ответ уже был.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
PD>>На вопрос же насчет передачи управления пользовательскому коду, я так понимаю, ответа не будет ?
AVK>Ответ уже был.
Вот это ? Это не ответ.
AV>Сейчас — никакой. А вот есть там кастомный дефолтный конструктор будет, то все не так однозначно.
Впрочем, что я... Я и забыл, что имею дело с человеком, который никогда не признает своих ошибок. Все, умолкаю.
Здравствуйте, Pavel Dvorkin, Вы писали:
AVK>>Ответ уже был. PD>Вот это ? Это не ответ. AV>>Сейчас — никакой. А вот есть там кастомный дефолтный конструктор будет, то все не так однозначно.
Нет, не это. А вот это:
Конструктор ведь может прочесть собственные поля, верно? И что за данные там будут, если их предварительно не потереть?
PD>Впрочем, что я... Я и забыл, что имею дело с человеком, который никогда не признает своих ошибок. Все, умолкаю.
Переход на личности, фу.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
PD>Размещение в стеке, а не в куче.
PD>В общем, с тем, что ты написал, я могу согласиться, но только пока речь идет о простых данных (кстати, заметь, в С++ у них нет конструктора вообще, ни с параметрами, ни дефолтного, а вот инициализация ненулем есть, как простых переменных, так и массивов, правда, для массива лишь списком, а не циклом). А вот когда речь идет о структурах, а хочется иметь их в стеке — машинный код должен , во-первых, выделить место в стеке (это элементарно), а потом инициализировать структуру. И вот тут инициализация нулем действительно очень проста. Если же инициализировать нужно не нулем, то все равно происходит инициализация нулем, а потом устанавливаем ненулевые поля. Лишние действия.
Так на этот случай есть unsafe:
MyStruct* block = stackalloc MyStruct[100];
Ничего не вызывает, память 0 не забивает. Самый быстрый способ выделить память в стеке. Инициализируй на здоровье любыми данными, только уж сам обезопасть себя от выстрела в ногу в виде мусора в не инициализированных полях. Как-то я этим даже пользовался. Примерно в то же время мне не хватало конструкторов у структур. Проблема решилась, больше необходимости не возникало. Так что инструмент есть, а вокруг можно хоть аспекты городить, если это действительно нужно.
Делать безопасный кастомизируемый дефолтный коснструктор для структур не вижу смысла, так как единственный профит перед классами (быстрое выделение в стеке) моментально потеряется при работе в safe-контексте за счёт многократного копирования (а в случае массивов ещё и проверок выхода за пределы допустимого диапазона). В unsafe — пожалуйста, stackalloc и вперёд. .NET даже сам эту память почистит, после выхода из метода, так что возможности застрелиться существенно меньше чем в том же С++.
Здравствуйте, VTT, Вы писали:
VTT>Ясное дело, что занулить блок памяти — это просто и быстро. Но когда 0 по-умолчанию не устраивают, то все равно потом придется пробежаться по массиву и инициализировать нужные поля вручную. То есть по сути выполнив N раз тот самый конструктор по-умолчанию, который компилятор не удосуживается выполнить сам. Где тут профит в производительности?
В статье написано, что это накладно для разработчиков CLR. Лишние телодвижения.