LINUX.ORG.RU

История изменений

Исправление r--r--r--, (текущая версия) :

Для for(int i = x; i != y; i++) { … a[i] … } есть гарантия, что массив a читается последовательно (можно предсказуемо подгружать кэш и использовать всякие SIMD).

Для unsigned всё становится заметно сложнее: либо делать проверку и удваивать объём кода, либо не иметь гарантии последовательного чтения.

В смысле? Вот цикл for(unsigned char i = x; i!= y; i++) { …a[i]… }. Он завершается.

Потому что может доказать, что переполнения нет. Доступ к array[i] гарантирует, что i не больше 1024.

Ладно про стандарт, но с компиляторами-то ты свои фантазии как-то пытался соотнести?

  1. В реальности для знаковых компилятор тупо выбрасывает проверку недостижимого (с его, компилятора, точки зрения) условия , превращая цикл в вечный не зависимо от sizeof(array) и "Доступ к array[i] гарантирует, что i не больше 1024."©™.

  2. Если компилятор НЕ может доказать, что нет переполнения, так как sizeof(array) не известен, то они генерируют идентичный код для знаковых и беззнаковых счётчиков.

Для for(int i = x; i != y; i++) { … a[i] … } есть гарантия, что массив a читается последовательно (можно предсказуемо подгружать кэш и использовать всякие SIMD).

Но вместо этого, компилятор просто выкинет нахер условие, если может.

Для unsigned всё становится заметно сложнее: либо делать проверку и удваивать объём кода, либо не иметь гарантии последовательного чтения.

Ты хоть один реально существующий компилятор, который вместо неимения гарантий будет городить какие-то проверки сверх описанных в коде, сможешь привести?

Исправление r--r--r--, :

Для for(int i = x; i != y; i++) { … a[i] … } есть гарантия, что массив a читается последовательно (можно предсказуемо подгружать кэш и использовать всякие SIMD).

Для unsigned всё становится заметно сложнее: либо делать проверку и удваивать объём кода, либо не иметь гарантии последовательного чтения.

В смысле? Вот цикл for(unsigned char i = x; i!= y; i++) { …a[i]… }. Он завершается.

Потому что может доказать, что переполнения нет. Доступ к array[i] гарантирует, что i не больше 1024.

Ладно про стандарт, но с компиляторами-то ты свои фантазии как-то пытался соотнести?

  1. В реальности для знаковых компилятор тупо выбрасывает проверку недостижимого условия, превращая цикл в вечный не зависимо от sizeof(array) и "Доступ к array[i] гарантирует, что i не больше 1024."©™.

  2. Если компилятор НЕ может доказать, что нет переполнения, так как sizeof(array) не известен, то они генерируют идентичный код для знаковых и беззнаковых счётчиков.

Для for(int i = x; i != y; i++) { … a[i] … } есть гарантия, что массив a читается последовательно (можно предсказуемо подгружать кэш и использовать всякие SIMD).

Но вместо этого, компилятор просто выкинет нахер условие, если может.

Для unsigned всё становится заметно сложнее: либо делать проверку и удваивать объём кода, либо не иметь гарантии последовательного чтения.

Ты хоть один реально существующий компилятор, который вместо неимения гарантий будет городить какие-то проверки сверх описанных в коде, сможешь привести?

Исходная версия r--r--r--, :

Для for(int i = x; i != y; i++) { … a[i] … } есть гарантия, что массив a читается последовательно (можно предсказуемо подгружать кэш и использовать всякие SIMD).

Для unsigned всё становится заметно сложнее: либо делать проверку и удваивать объём кода, либо не иметь гарантии последовательного чтения.

В смысле? Вот цикл for(unsigned char i = x; i!= y; i++) { …a[i]… }. Он завершается.

Потому что может доказать, что переполнения нет. Доступ к array[i] гарантирует, что i не больше 1024.

Ладно про стандарт, но с компиляторами-то ты свои фантазии как-то пытался соотнести?

  1. В реальности для знаковых компилятор тупо выбрасывает проверку недостижимого условия, превращая цикл в вечный не зависимо от sizeof(array) и "Доступ к array[i] гарантирует, что i не больше 1024."©™.

  2. Если компилятор НЕ может доказать, что нет переполнения, так как sizeof(array) не известен, то они генерируют идентичный код для знаковых и беззнаковых счётчиков.