LINUX.ORG.RU

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

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

UB написали не потому что язык Си

Именно потому. Причём ты не прав аж два раза в этой простой фразе.

Во-первых

сначала наплодили кучу компиляторов с разным генератором кода и разным поведением и кучей опций меняющих это поведение как явно так и неявно, а потом только это решили поместить стандарт

Это и есть то, что сформировало Си - куча разных компиляторов более-менее похожих друг на друга, но не во всём. Другого Си нет.

Во-вторых, UB при signed переполнении в современном исполнении сделано не из-за этого, а для того, чтобы оптимизатору было проще выкидывать твой код при работе.

Например, чтобы он мог из подобного кода:

f(int x) {
  int y;
  y = x+5;
  if(y<x) { ... }
  ...
}
выкинуть целиком весь if и не думать о том, что x+5 могло переполниться и стать меньше чем x. Реальные примеры такого выкидывания разумеется выглядят сложнее, между y=x+5 и if-ом может быть разный другой код (не меняющий x и y), сама константа 5 да и вообще операция сложения, как и условие в if, может быть спрятана за пачкой макросов так, что при взгляде на реальный исходник возможность этого выкидывания совсем не очевидна. А вот после препроцессирования и трассировки кода компилятор выясняет, что код сводится к такому как выше, и решает что x+5 всегда больше чем x, а значит ветка if-а - мёртвый код.

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

UB написали не потому что язык Си

Именно потому. Причём ты не прав аж два раза в этой простой фразе.

Во-первых

сначала наплодили кучу компиляторов с разным генератором кода и разным поведением и кучей опций меняющих это поведение как явно так и неявно, а потом только это решили поместить стандарт

Это и есть то, что сформировало Си - куча разных компиляторов более-менее похожих друг на друга, но не во всём. Другого Си нет.

Во-вторых, UB при signed переполнении сделано не из-за этого, а для того, чтобы оптимизатору было проще выкидывать твой код при работе.

Например, чтобы он мог из подобного кода:

f(int x) {
  int y;
  y = x+5;
  if(y<x) { ... }
  ...
}
выкинуть целиком весь if и не думать о том, что x+5 могло переполниться и стать меньше чем x. Реальные примеры такого выкидывания разумеется выглядят сложнее, между y=x+5 и if-ом может быть разный другой код (не меняющий x и y), сама константа 5 да и вообще операция сложения, как и условие в if, может быть спрятана за пачкой макросов так, что при взгляде на реальный исходник возможность этого выкидывания совсем не очевидна. А вот после препроцессирования и трассировки кода компилятор выясняет, что код сводится к такому как выше, и решает что x+5 всегда больше чем x, а значит ветка if-а - мёртвый код.

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

UB написали не потому что язык Си

Именно потому. Причём ты не прав аж два раза в этой просто фразе.

Во-первых

сначала наплодили кучу компиляторов с разным генератором кода и разным поведением и кучей опций меняющих это поведение как явно так и неявно, а потом только это решили поместить стандарт

Это и есть то, что сформировало Си - куча разных компиляторов более-менее похожих друг на друга, но не во всём. Другого Си нет.

Во-вторых, UB при signed переполнении сделано не из-за этого, а для того, чтобы оптимизатору было проще выкидывать твой код при работе.

Например, чтобы он мог из подобного кода:

f(int x) {
  int y;
  y = x+5;
  if(y<x) { ... }
  ...
}
выкинуть целиком весь if и не думать о том, что x+5 могло переполниться и стать меньше чем x. Реальные примеры такого выкидывания разумеется выглядят сложнее, между y=x+5 и if-ом может быть разный другой код (не меняющий x и y), сама константа 5 да и вообще операция сложения, как и условие в if, может быть спрятана за пачкой макросов так, что при взгляде на реальный исходник возможность этого выкидывания совсем не очевидна. А вот после препроцессирования и трассировки кода компилятор выясняет, что код сводится к такому как выше, и решает что x+5 всегда больше чем x, а значит ветка if-а - мёртвый код.