Информация об изменениях

Сообщение Re[117]: Мнение: объектно-ориентированное программирование — от 15.11.2019 11:34

Изменено 15.11.2019 11:37 Sinclair

Re[117]: Мнение: объектно-ориентированное программирование —
Здравствуйте, alex_public, Вы писали:
_>Ну я то писал про C++. Забавно, что в C# ситуация обратная. Кстати, а в какой код транслируется range for в C#? )
В С# range нету. Вместо них — Span<T>.
Он прекрасен тем, что позволяет сослаться на более-менее любую память. Наиболее популярный сценарий — кусок массива.
Так вот — он решает проблемы с детектированием границ:
public static void foo(int[] arr)
{
int64 sum = 0;
for(int i=0; i<arr.Count; i++)
sum+=arr[i]; // проверка устранена

int64 sum = 0;
for(int i=0; i<arr.Count-1; i++)
sum+=arr[i]; // проверка не устранена!

var subarray = new Span<int>(arr, 0, arr.Count-1); // один раз проверили границы здесь

int64 sum = 0;
for(int i=0; i<subarray.Count; i++)
sum+=subarray[i]; // проверка устранена!
}


_>Не значит. Если в теле цикла есть другой (модифицирующий) вызов a. Вот в случае константного a всё однозначно. А когда константности нет, то компилятор должен сам отслеживать и не всегда у него это удаётся верно.

Зависит от толщины тела. В простых случаях компилятор просто видит, что модифицирующих вызовов нет — всё, константность нам монопенисуальна.
Кстати, что будет, если a — константен, но внутри цикла мы имеем const_cast и принудительную модификацию? Всё падает, или компилятор видит палево и отменяет оптимизацию?
_>Причём ещё нюанс: нам не обязательно требовать именно чистоты функций, вызываемых в теле цикла. Главное чтобы они не меняли a (т.е. если вдруг у a есть функция, печатающая некую отладочную информацию в консоль, то это не должно помешать такой оптимизации).
Да. Понятия чистоты, детерминированности, константности — все разные, близкие, но могут применяться компилятором в различных сценариях.
Re[117]: Мнение: объектно-ориентированное программирование —
Здравствуйте, alex_public, Вы писали:
_>Ну я то писал про C++. Забавно, что в C# ситуация обратная. Кстати, а в какой код транслируется range for в C#? )
В С# range нету. Вместо них — Span<T>.
Он прекрасен тем, что позволяет сослаться на более-менее любую память. Наиболее популярный сценарий — кусок массива.
Так вот — он решает проблемы с детектированием границ:
public static void foo(int[] arr)
{
  int64 sum = 0; 
  for(int i=0; i<arr.Count; i++) 
    sum+=arr[i]; // проверка устранена

  int64 sum = 0; 
  for(int i=0; i<arr.Count-1; i++) 
    sum+=arr[i]; // проверка не  устранена!

  var subarray = new Span<int>(arr, 0, arr.Count-1); // один раз проверили границы здесь

  int64 sum = 0; 
  for(int i=0; i<subarray.Count; i++) 
    sum+=subarray[i]; // проверка устранена!
}


_>Не значит. Если в теле цикла есть другой (модифицирующий) вызов a. Вот в случае константного a всё однозначно. А когда константности нет, то компилятор должен сам отслеживать и не всегда у него это удаётся верно.

Зависит от толщины тела. В простых случаях компилятор просто видит, что модифицирующих вызовов нет — всё, константность нам монопенисуальна.
Кстати, что будет, если a — константен, но внутри цикла мы имеем const_cast и принудительную модификацию? Всё падает, или компилятор видит палево и отменяет оптимизацию?
_>Причём ещё нюанс: нам не обязательно требовать именно чистоты функций, вызываемых в теле цикла. Главное чтобы они не меняли a (т.е. если вдруг у a есть функция, печатающая некую отладочную информацию в консоль, то это не должно помешать такой оптимизации).
Да. Понятия чистоты, детерминированности, константности — все разные, близкие, но могут применяться компилятором в различных сценариях.