Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 11.10.18 14:13
Оценка: +1
Есть ли какое-то практическое обоснование тому, что в C++ до сих разрешено неявное усечение значений (например, int до char)? Мне сложно понять такие неявные усечения даже в ранних версиях C, но там их еще можно худо-бедно оправдать стремлением видеть программу как можно более компактной по тексту, и общепринятым в те времена подходом "в таких языках программист должен сам следить за типами". По идее, уже в первых версиях C++ это следовало изжить, но обошлись лишь введением предупреждений компилятора. Позже добавили автоматические проверки в run-time.

Все бы ничего, но при вызове перегруженных функций из шаблонов других функций это превращается в кошмар. Например, для фактической комбинации параметров (short, int) компиляторы считают подходящими и (int, int), и (short, short), и (char, char). Что мешает в такой ситуации выбрать единственно безопасный (int, int)?

Ради чего это неявное усечение продолжают тянуть? Из старого кода вроде бы уже давно должны быть вычистить требующие его конструкции, а за использование их в новом коде — расстреливать на месте. Но в C++14 на эту тему все по-прежнему (текст C++17 сходу не нашелся).
value truncation conversion
Re: Есть ли практический смысл в неявном усечении значений?
От: Lepsik Индия figvam.ca
Дата: 11.10.18 18:47
Оценка: -1
ЕМ>Ради чего это неявное усечение продолжают тянуть? Из старого кода вроде бы уже давно должны быть вычистить требующие его конструкции, а за использование их в новом коде — расстреливать на месте. Но в C++14 на эту тему все по-прежнему (текст C++17 сходу не нашелся).

Пользуйтесь __int8, __int16, __int32, __int64
Re[2]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 11.10.18 20:14
Оценка:
Здравствуйте, Lepsik, Вы писали:

L>Пользуйтесь __int8, __int16, __int32, __int64


Почему Вы решили, будто я ими не пользуюсь?
Re: Есть ли практический смысл в неявном усечении значений?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 14.10.18 03:56
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Есть ли какое-то практическое обоснование тому, что в C++ до сих разрешено неявное усечение значений (например, int до char)?


Спроси в std-proposals, как это лучше ограничить...

Вообще, там в целочисленной арифметике и без этого паршиво.

ЕМ>Все бы ничего, но при вызове перегруженных функций из шаблонов других функций это превращается в кошмар. Например, для фактической комбинации параметров (short, int) компиляторы считают подходящими и (int, int), и (short, short), и (char, char). Что мешает в такой ситуации выбрать единственно безопасный (int, int)?


Ну если на то пошло, то автоматически должен выбираться только (short, int), все остальные только по явной конверсии.
Если уж делаете строгость типизации в этом месте — то не должно быть неявных конверсий вообще.
Разве что для констант.

ЕМ>Ради чего это неявное усечение продолжают тянуть? Из старого кода вроде бы уже давно должны быть вычистить требующие его конструкции, а за использование их в новом коде — расстреливать на месте. Но в C++14 на эту тему все по-прежнему (текст C++17 сходу не нашелся).


А как поддерживать легаси?

Я вижу пока только один вариант — вводить [[атрибутами]] контексты, где действуют новые правила.
The God is real, unless declared integer.
Отредактировано 14.10.2018 3:57 netch80 . Предыдущая версия .
Re: Есть ли практический смысл в неявном усечении значений?
От: -MyXa- Россия  
Дата: 14.10.18 05:02
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>в C++ до сих разрешено неявное усечение значений


Не нравится — запрети. -Werror=conversion или -Werror=implicit-int-conversion.
Если не поможет, будем действовать током... 600 Вольт (C)
Re[2]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 14.10.18 08:54
Оценка:
Здравствуйте, netch80, Вы писали:

N>Спроси в std-proposals, как это лучше ограничить...


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

ЕМ>>для фактической комбинации параметров (short, int) компиляторы считают подходящими и (int, int), и (short, short), и (char, char). Что мешает в такой ситуации выбрать единственно безопасный (int, int)?


N>Ну если на то пошло, то автоматически должен выбираться только (short, int), все остальные только по явной конверсии.


А если его нет? Чего ради компилятору в этой ситуации упираться в формализм и отказываться компилировать, когда он может выбрать заведомо безопасное преобразование?

N>Если уж делаете строгость типизации в этом месте — то не должно быть неявных конверсий вообще.


Тогда количество явных (то есть, ручных) определений функций с тремя-четырьмя параметрами стремится к сотне. Это действительно то, чего ожидали от программиста, предлагая ему шаблоны функций и их перегрузку? Ну, или эквилибристика с метапрограммированием, но это ж чистой воды извращение.

ЕМ>>Ради чего это неявное усечение продолжают тянуть?


N>А как поддерживать легаси?


Зачем поддерживать то легаси, к которому минимум двадцать лет никто не прикасался? Еще на стыка 90-х и 2000-х следовало объявить, что в будущем неявные усекающие преобразования будут изжиты, и на приведение программ в порядок дается, скажем, десять лет. Этого хватило бы с избытком, и в итоге проблема давно была бы ликвидирована в корне, и сейчас было бы одной головной болью меньше.

Пример налицо — переходный период от 32- к 64-разрядному коду. Пока раскладка по типам не устаканилось окончательно, в ряде компиляторов были специальные предупреждения на этот счет. Нынче 64-разрядные типы в языке ничем не отличаются от 8- или 16-разрядных, так что как-то специально их отличать уже нет нужды. Все, кому было нужно, привели свои программы в порядок, а зачем тратить ресурсы на заботу о лентяях?

Я реально не понимаю, каким образом столь дикая и абсурдная идея, как неявное усечение, могла выжить в серьезном и популярном языке столько лет, на фоне постоянных хлопот об исключении куда менее опасных ситуаций.

N>Я вижу пока только один вариант — вводить [[атрибутами]] контексты, где действуют новые правила.


Это само собой, когда нужно заставить компилятор выбрать более эффективный или иным образом подходящий вариант. Но он сам должен предпочитать безопасные способы безусловно опасным.
Re[2]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 14.10.18 08:56
Оценка:
Здравствуйте, -MyXa-, Вы писали:

MX>Не нравится — запрети. -Werror=conversion или -Werror=implicit-int-conversion.


Это запретит компилятору выбирать усекающие варианты из набора перегруженных/шаблонных функций? У меня в MS VC++ таких ключей нет, поэтому проверить не на чем.
Re: Есть ли практический смысл в неявном усечении значений?
От: _NN_ www.nemerleweb.com
Дата: 14.10.18 10:39
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

Скорее всего вначале сделали, чтобы было как в C, а сейчас уже изменить сломает много кода.

Поэтому и неявное приведение 0 в указатель до сих пор осталось несмотря на то, что появился nullptr.
В GCC правда есть флаг и для этого тоже zero-as-null-pointer-constant
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 14.10.18 13:12
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Скорее всего вначале сделали, чтобы было как в C


Не скорее всего, а так и было. Но со временем-то многое меняется. Когда-то считалось хорошим тоном проверять на нуль или не нуль без операции сравнения, затем это потеряло смысл, а позже такой стиль стал справедливо осуждаться, как невнятный. По-хорошему, стандарты должны следовать за практикой.

_NN>а сейчас уже изменить сломает много кода.


Точнее — говнокода. Стоит ли об этом печалиться? На худой конец, добавить в компиляторы ключи для явного переключения в совместимый режим. Так ведь нет даже ключей, явно переключающих в нормальный. Как в такой ситуации можно верить в адекватность разработчиков стандарта?

_NN>Поэтому и неявное приведение 0 в указатель до сих пор осталось несмотря на то, что появился nullptr.


nullptr появился не так давно. И с нулем тоже нужно что-то делать — по крайней мере, иметь для этого возможность.

_NN>В GCC правда есть флаг и для этого тоже zero-as-null-pointer-constant


А где-то еще подобный флаг есть?
Re[3]: Есть ли практический смысл в неявном усечении значений?
От: _NN_ www.nemerleweb.com
Дата: 14.10.18 13:37
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

_NN>>а сейчас уже изменить сломает много кода.


ЕМ>Точнее — говнокода. Стоит ли об этом печалиться? На худой конец, добавить в компиляторы ключи для явного переключения в совместимый режим. Так ведь нет даже ключей, явно переключающих в нормальный. Как в такой ситуации можно верить в адекватность разработчиков стандарта?

Пока в нём есть великий и ужасный iostream в адекватность верить не получается

ЕМ>А где-то еще подобный флаг есть?

Не знаю. Возможно в clang.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 14.10.18 13:46
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Пока в нём есть великий и ужасный iostream в адекватность верить не получается


iostream нет в языке C++.
Re[5]: Есть ли практический смысл в неявном усечении значений?
От: _NN_ www.nemerleweb.com
Дата: 17.10.18 12:30
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, _NN_, Вы писали:


_NN>>Пока в нём есть великий и ужасный iostream в адекватность верить не получается


ЕМ>iostream нет в языке C++.

Т.е. то, что в стандарте не является частью языка C++ ?
По этой логике std::initializer_list , std::type_info тоже не часть языка ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 17.10.18 14:21
Оценка:
Здравствуйте, _NN_, Вы писали:

ЕМ>>iostream нет в языке C++.

_NN>Т.е. то, что в стандарте не является частью языка C++ ?

Это часть исполняющей системы языка C++. Язык — это синтаксис+семантика, остальное — внешнее.

_NN>По этой логике std::initializer_list , std::type_info тоже не часть языка ?


Если в любой из реализаций оно определено непосредственно в компиляторе (то есть, доступно всегда и безусловно), то часть языка.
Re[7]: Есть ли практический смысл в неявном усечении значений?
От: B0FEE664  
Дата: 17.10.18 14:38
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Если в любой из реализаций оно определено непосредственно в компиляторе (то есть, доступно всегда и безусловно), то часть языка.


Теоретически вся std библиотека может находится внутри компилятора в бинарном виде.
И каждый день — без права на ошибку...
Re[8]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 17.10.18 18:02
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Теоретически вся std библиотека может находится внутри компилятора в бинарном виде.


Теоретически не есть практически.
Re[7]: Есть ли практический смысл в неявном усечении значений?
От: N. I.  
Дата: 18.10.18 20:56
Оценка:
Евгений Музыченко:

_NN>>Т.е. то, что в стандарте не является частью языка C++ ?


ЕМ>Это часть исполняющей системы языка C++. Язык — это синтаксис+семантика, остальное — внешнее.


Это по чьей классификации?

_NN>>По этой логике std::initializer_list , std::type_info тоже не часть языка ?


ЕМ>Если в любой из реализаций оно определено непосредственно в компиляторе (то есть, доступно всегда и безусловно), то часть языка.


А если, например, исключения не поддерживаются или их можно отключить, то exception handling — это уже типа не часть языка?
Re[8]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 20.10.18 05:29
Оценка:
Здравствуйте, N. I., Вы писали:

ЕМ>>Язык — это синтаксис+семантика, остальное — внешнее.


NI>Это по чьей классификации?


По классической. Языки программирования относятся к классу формальных языков, и лексика/синтаксис/семантика определяют тип языка.

NI>А если, например, исключения не поддерживаются или их можно отключить, то exception handling — это уже типа не часть языка?


От того, что какие-то возможности языка не реализованы или отключены, их суть не меняется.

Если считать библиотеки расширения частью языка, а не исполняющей средой, то можно договориться и до того, что plain C путем добавления нужных библиотек становится объектно-ориентированным или функциональным языком.
Re[3]: Есть ли практический смысл в неявном усечении значений?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 20.10.18 06:16
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

N>>Спроси в std-proposals, как это лучше ограничить...

ЕМ>Есть же совершенно очевидный вариант — ограничивать (по крайней мере, по умолчанию) все неявные усекающие преобразования, когда на этапе компиляции нет гарантии, что они не приводят к потере значащих разрядов.

Я бы согласился, но с подобными решениями вечно возникают какие-то подводные камни.
А так — да, но если нет таких гарантий, то нужно выбирать метод усечения.

ЕМ>>>Ради чего это неявное усечение продолжают тянуть?

N>>А как поддерживать легаси?
ЕМ>Зачем поддерживать то легаси, к которому минимум двадцать лет никто не прикасался? Еще на стыка 90-х и 2000-х следовало объявить, что в будущем неявные усекающие преобразования будут изжиты, и на приведение программ в порядок дается, скажем, десять лет. Этого хватило бы с избытком, и в итоге проблема давно была бы ликвидирована в корне, и сейчас было бы одной головной болью меньше.

Тут согласен, и это не единственное такое место. Но почему-то стандартизаторам не интересно.

ЕМ>Пример налицо — переходный период от 32- к 64-разрядному коду. Пока раскладка по типам не устаканилось окончательно, в ряде компиляторов были специальные предупреждения на этот счет.


Ну вообще-то она и сейчас не устаканилась, в том смысле, что есть извращённые платформы, где long == int32_t

ЕМ>Я реально не понимаю, каким образом столь дикая и абсурдная идея, как неявное усечение, могла выжить в серьезном и популярном языке столько лет, на фоне постоянных хлопот об исключении куда менее опасных ситуаций.


N>>Я вижу пока только один вариант — вводить [[атрибутами]] контексты, где действуют новые правила.


ЕМ>Это само собой, когда нужно заставить компилятор выбрать более эффективный или иным образом подходящий вариант. Но он сам должен предпочитать безопасные способы безусловно опасным.


С нынешними нормами undefined behavior везде, куда могли впихнуть — это так не получится.
The God is real, unless declared integer.
Re[4]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 20.10.18 06:48
Оценка:
Здравствуйте, netch80, Вы писали:

ЕМ>>ограничивать (по крайней мере, по умолчанию) все неявные усекающие преобразования, когда на этапе компиляции нет гарантии, что они не приводят к потере значащих разрядов.


N>Я бы согласился, но с подобными решениями вечно возникают какие-то подводные камни.


Например? Особенно в грамотно написанном коде, а не наколенно-рубленом.

N>если нет таких гарантий, то нужно выбирать метод усечения.


Для его его может быть нужно выбирать неявно? Почему не следует потребовать явного приведения к целевому типу? На худой конец — использовать опцию компилятора или прагму.

N>Но почему-то стандартизаторам не интересно.


Ну дык, стандартизаторы озабочены в первую очередь модными направлениями, куда им до подобной мелочи...

N>есть извращённые платформы, где long == int32_t


Чем, по-Вашему, они извращенные? На мой взгляд, такой выбор исходит из того, что 32-разрядная сетка вполне достаточна для представления большинства "умеренно больших" значений, поэтому нет особого смысла делать long 64-разрядным, даже при наличии аппаратной поддержки. Более того, я до последнего времени никогда не вглядывался внимательно в особенности 64-разрядного кода на x64, и наивно полагал, что 64-разрядные значения для x64 "родные", а использование 32-разрядных порождает избыточный код. По этой причине несколько лет назад переделал все переменные, хранившие даже небольшие значения типа размера, в size_t.

А недавно включил кодовый листинг, и обнаружил, что большинство 64-разрядных команд минимум на байт длиннее. То есть, основной режим обработки остался 32-разрядным, и это правильно, а стремление использовать 64-разрядные вычисления без необходимости — неправильно.

ЕМ>>Но он сам должен предпочитать безопасные способы безусловно опасным.


N>С нынешними нормами undefined behavior везде, куда могли впихнуть — это так не получится.


Вот чтоб не возникало undefined behavior, криворуких программистов нужно бить по кривым рукам как можно чаще. И компилятор это сделает эффективнее любого препода или начальника.
Re[5]: Есть ли практический смысл в неявном усечении значений?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 20.10.18 08:58
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>>>ограничивать (по крайней мере, по умолчанию) все неявные усекающие преобразования, когда на этапе компиляции нет гарантии, что они не приводят к потере значащих разрядов.

N>>Я бы согласился, но с подобными решениями вечно возникают какие-то подводные камни.
ЕМ>Например? Особенно в грамотно написанном коде, а не наколенно-рубленом.

Вопрос не в самом коде, а в том, как это надо описать в стандарте, чтобы все согласились.

N>>если нет таких гарантий, то нужно выбирать метод усечения.

ЕМ>Для его его может быть нужно выбирать неявно? Почему не следует потребовать явного приведения к целевому типу? На худой конец — использовать опцию компилятора или прагму.

Я как раз имею в виду, что в явном варианте конверсия может быть как минимум truncating, checked, saturating...

N>>есть извращённые платформы, где long == int32_t


ЕМ>Чем, по-Вашему, они извращенные?


Ну если у одного и того же софтостроителя в C++ long == int32_t, а в C# long == Int64, а на чуть менее чем всех платформах вокруг тоже long == int64_t, то сомнений нет, где извращение.
Особенно учитывая, что в юниксах переход на 64 бита к тому времени состоялся, все грабли пройдены, и "собственная гордость" была тупо нелепа.

EM> На мой взгляд, такой выбор исходит из того, что 32-разрядная сетка вполне достаточна для представления большинства "умеренно больших" значений, поэтому нет особого смысла делать long 64-разрядным, даже при наличии аппаратной поддержки. Более того, я до последнего времени никогда не вглядывался внимательно в особенности 64-разрядного кода на x64, и наивно полагал, что 64-разрядные значения для x64 "родные", а использование 32-разрядных порождает избыточный код. По этой причине несколько лет назад переделал все переменные, хранившие даже небольшие значения типа размера, в size_t.


ЕМ>А недавно включил кодовый листинг, и обнаружил, что большинство 64-разрядных команд минимум на байт длиннее. То есть, основной режим обработки остался 32-разрядным, и это правильно, а стремление использовать 64-разрядные вычисления без необходимости — неправильно.


Ну так и можно было обойтись int в таких местах.

ЕМ>>>Но он сам должен предпочитать безопасные способы безусловно опасным.

N>>С нынешними нормами undefined behavior везде, куда могли впихнуть — это так не получится.
ЕМ>Вот чтоб не возникало undefined behavior, криворуких программистов нужно бить по кривым рукам как можно чаще. И компилятор это сделает эффективнее любого препода или начальника.

Не-а. Он не бьёт, он слишком часто маскирует это.
The God is real, unless declared integer.
Re[5]: Есть ли практический смысл в неявном усечении значений?
От: N. I.  
Дата: 20.10.18 09:00
Оценка:
Евгений Музыченко:

ЕМ>Для его его может быть нужно выбирать неявно? Почему не следует потребовать явного приведения к целевому типу?


А для чего вообще нужны неявные преобразования? Давай везде начнём касты вставлять — то-то красота будет!

std::uint8_t x = 10;
std::uint8_t y = 20;
std::uint8_t z = x + y; // Видишь тут усекающее преобразование?

std::uint8_t x = 10;
std::uint8_t y = 20;
std::uint8_t z = x & y; // А тут?

То, что ты хочешь, наверное, можно было бы как-то формализовать, только вот правила, скорее всего, получатся ещё заметно более сложные, чем есть сейчас, при том, что в текущих правилах уже без поллитры не разберёшься.
Re[9]: Есть ли практический смысл в неявном усечении значени
От: N. I.  
Дата: 20.10.18 09:00
Оценка:
Евгений Музыченко:

ЕМ>Если считать библиотеки расширения частью языка, а не исполняющей средой


Впервые вижу, чтоб standard library называли execution environment. ХЗ, откуда ты берёшь эти свои понятия, но в среде людей, имеющих непосредственное отношение к стандартизации C++ и разработке его реализаций, принято считать, что язык C++ состоит из двух основных частей: C++ core language и C++ standard library. Стандартная библиотека C++ вся целиком является неотъемлемой частью языка — так же, как и core language.
Отредактировано 20.10.2018 9:02 N. I. . Предыдущая версия .
Re[6]: Есть ли практический смысл в неявном усечении значений?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 20.10.18 09:18
Оценка:
Здравствуйте, N. I., Вы писали:

ЕМ>>Для его его может быть нужно выбирать неявно? Почему не следует потребовать явного приведения к целевому типу?

NI>А для чего вообще нужны неявные преобразования? Давай везде начнём касты вставлять — то-то красота будет!

Ну так в Go так и сделано. И далеко не только в нём.

NI>std::uint8_t x = 10;

NI>std::uint8_t y = 20;
NI>std::uint8_t z = x + y; // Видишь тут усекающее преобразование?

А зачем было нужно безусловное расширяющее, чтобы потом усекать? Можно и без него.

NI>То, что ты хочешь, наверное, можно было бы как-то формализовать, только вот правила, скорее всего, получатся ещё заметно более сложные, чем есть сейчас, при том, что в текущих правилах уже без поллитры не разберёшься.


Как раз если устранить и неявное усечение, и неявное расширение — правила станут резко проще.
И, более того, это будет стимулировать понимание сути происходящего.
The God is real, unless declared integer.
Re[7]: Есть ли практический смысл в неявном усечении значений?
От: N. I.  
Дата: 20.10.18 09:26
Оценка:
netch80:

N>А зачем было нужно безусловное расширяющее, чтобы потом усекать?


Не помню уже...

N>Можно и без него.


Вот только старый код, использующий promotions, по-тихому сломается.

N>Как раз если устранить и неявное усечение, и неявное расширение — правила станут резко проще.


А со старым кодом что делать прикажете?
Re[8]: Есть ли практический смысл в неявном усечении значений?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 20.10.18 10:31
Оценка: 8 (1) +1
Здравствуйте, N. I., Вы писали:

N>>А зачем было нужно безусловное расширяющее, чтобы потом усекать?

NI>Не помню уже...



N>>Можно и без него.

NI>Вот только старый код, использующий promotions, по-тихому сломается.
N>>Как раз если устранить и неявное усечение, и неявное расширение — правила станут резко проще.
NI>А со старым кодом что делать прикажете?

Опции регулирования контекста. Например, в стиле

[[promotion(off)]] int func() {
    // На функцию, метод, блок или выражение
    ...
}


или

#pragma STDC promotion(off)
// До конца блока того же уровня
...


Без них — старый стиль поведения (если опциями компилятора не меняется), с ними — как угодно.

Точно так же контекстными опциями стоило бы регулировать
— Режим целочисленной арифметики (truncated, checked...)
— Режим плавающей арифметики (так лучше, чем через runtime настройки типа fesetenv)
— Режим алиасинга
и многое другое.
The God is real, unless declared integer.
Re[9]: Есть ли практический смысл в неявном усечении значени
От: N. I.  
Дата: 20.10.18 12:07
Оценка:
netch80:

N>Опции регулирования контекста. Например, в стиле


Если перед тобой появляется куча незнакомого кода, то быстро на глазок определить, нужно ли к нему присобачивать такие опции, может быть несколько затруднительно. Кроме того, это для нас добавление в компилятор очередной опции может казаться всего лишь парой пустяков, а для разработчиков компиляторов появление новых опций совместимости — это тот ещё геморрой, т.к. усложняет и без того непростую реализацию, а также её тестирование, покуда во всех допустимых комбинациях они должны между собой дружить. Когда опций много, возможных комбинаций их использования получается ну очень много и тогда можно легко нарваться на какие-нибудь неочевидные corner cases, поскольку уследить за всеми потенциальными взаимодействиями становится просто нереально.

Собсно, стандартизаторам в пределах одной версии стандарта все правила между собой нормально согласовать не удаётся, а вы ещё хотите, чтоб разработчики компиляторов вам покусочно разные версии стандарта согласовали. Ну, предположим, сделают они вам очередную прагму, вот только далеко не факт, что она всегда будет работать так, как вы желаете.
Отредактировано 20.10.2018 12:28 N. I. . Предыдущая версия . Еще …
Отредактировано 20.10.2018 12:16 N. I. . Предыдущая версия .
Re[10]: Есть ли практический смысл в неявном усечении значен
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 20.10.18 12:51
Оценка:
Здравствуйте, N. I., Вы писали:

N>>Опции регулирования контекста. Например, в стиле


NI>Если перед тобой появляется куча незнакомого кода, то быстро на глазок определить, нужно ли к нему присобачивать такие опции, может быть несколько затруднительно.


С какого потолка взято про "быстро" "присобачивать"?

NI> Кроме того, это для нас добавление в компилятор очередной опции может казаться всего лишь парой пустяков, а для разработчиков компиляторов появление новых опций совместимости — это тот ещё геморрой, т.к. усложняет и без того непростую реализацию, а также её тестирование, покуда во всех допустимых комбинациях они должны между собой дружить. Когда опций много, возможных комбинаций их использования получается ну очень много и тогда можно легко нарваться на какие-нибудь неочевидные corner cases, поскольку уследить за всеми потенциальными взаимодействиями становится просто нереально.


1. Взаимодействовать тут нечему.
2. Эти отмазки слышны уже лет 20. "Кто хочет — ищет метод, кто не хочет — ищет причину".

NI>Собсно, стандартизаторам в пределах одной версии стандарта все правила между собой нормально согласовать не удаётся,


То, что я назвал, им никак тут не помешает (и не поможет, оно просто ортогонально), так же как какие-нибудь -fwrapv или -Og.

NI> а вы ещё хотите, чтоб разработчики компиляторов вам покусочно разные версии стандарта согласовали. Ну, предположим, сделают они вам очередную прагму, вот только далеко не факт, что она всегда будет работать так, как вы желаете.


Таки поиск причины не делать.
The God is real, unless declared integer.
Отредактировано 20.10.2018 12:53 netch80 . Предыдущая версия .
Re[11]: Есть ли практический смысл в неявном усечении значен
От: N. I.  
Дата: 20.10.18 13:49
Оценка:
netch80:

NI>>Если перед тобой появляется куча незнакомого кода, то быстро на глазок определить, нужно ли к нему присобачивать такие опции, может быть несколько затруднительно.


N>С какого потолка взято про "быстро" "присобачивать"?


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

NI>> Кроме того, это для нас добавление в компилятор очередной опции может казаться всего лишь парой пустяков, а для разработчиков компиляторов появление новых опций совместимости — это тот ещё геморрой, т.к. усложняет и без того непростую реализацию, а также её тестирование, покуда во всех допустимых комбинациях они должны между собой дружить. Когда опций много, возможных комбинаций их использования получается ну очень много и тогда можно легко нарваться на какие-нибудь неочевидные corner cases, поскольку уследить за всеми потенциальными взаимодействиями становится просто нереально.


N>1. Взаимодействовать тут нечему.


Откуда такая уверенность, если ты даже не в курсе, зачем эти promotions нужны?

N>2. Эти отмазки слышны уже лет 20. "Кто хочет — ищет метод, кто не хочет — ищет причину".


N>Таки поиск причины не делать.


Ну, да, некоторым людям вообще-то своственно рассматривать pros & cons. Трудности в реализации и поддержки с виду полезной фичи могут перевешивать её достоинства.
Re[6]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 20.10.18 14:01
Оценка:
Здравствуйте, netch80, Вы писали:

N>как это надо описать в стандарте, чтобы все согласились.


Навскидку, пара вариантов. Мягкий: запрещено любое неявное усечение, кроме следствий неявного же расширения (например, i8 = i8+i8 разрешено, а i8 = i16 запрещено). Жесткий: запрещено любое неявное усечение, без вариантов.

N>Я как раз имею в виду, что в явном варианте конверсия может быть как минимум truncating, checked, saturating...


Это уже детали, которые можно было бы указывать или конструкцией явного преобразования, или явно же задаваемым режимом.

N>Ну если у одного и того же софтостроителя в C++ long == int32_t, а в C# long == Int64, а на чуть менее чем всех платформах вокруг тоже long == int64_t, то сомнений нет, где извращение.


У меня таки сомнения. Ибо триада short-int-long устаканивалась во времена, когда 32 разрядов хватало практически на все и, с переходом к 64-разрядным платформам, бОльшую разрядность почти везде стали задавать явно.

N>Особенно учитывая, что в юниксах переход на 64 бита к тому времени состоялся, все грабли пройдены, и "собственная гордость" была тупо нелепа.


Дело не в гордости, а в том, что юниксы устаканивались в первую очередь на RISC'ах, у которых длина команды не зависит от разрядности операндов. А статистика по коду с командами переменной длины показала, что операций с 64-разрядными операндами значительно меньше, чем с 32-разрядными, и в случае родных 64-разрядных и префиксованных 32-разрядных код будет раздуваться чересчур неприлично.

EM>>По этой причине несколько лет назад переделал все переменные, хранившие даже небольшие значения типа размера, в size_t.


N>Ну так и можно было обойтись int в таких местах.


Раньше там и был int, но все время приходилось ставить явные преобразования, получая ту же длину строки, или смещение в небольшом блоке памяти. Само по себе это не напрягает, но тогда мне казалось, что это еще и бессмысленно с точки зрения оптимальности кода.

ЕМ>>криворуких программистов нужно бить по кривым рукам как можно чаще. И компилятор это сделает эффективнее любого препода или начальника.


N>Не-а. Он не бьёт, он слишком часто маскирует это.


А вот зачем? Или в комитете по стандартизации криворуких слишком много?
Re[6]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 20.10.18 14:04
Оценка: +1
Здравствуйте, N. I., Вы писали:

NI>То, что ты хочешь, наверное, можно было бы как-то формализовать, только вот правила, скорее всего, получатся ещё заметно более сложные, чем есть сейчас, при том, что в текущих правилах уже без поллитры не разберёшься.


Я согласен с предыдущим ответом — неявное расширение тоже следовало бы исключить. Ибо оно в одних случаях делается, в других нет, увидеть это в выражении сходу, без выяснения всех участвующих типов, невозможно. Поэтому лучше бы сложение 8-разрядных всегда работало в 8-разрядной сетке, и так далее.
Re[10]: Есть ли практический смысл в неявном усечении значени
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 20.10.18 14:16
Оценка:
Здравствуйте, N. I., Вы писали:

NI>принято считать, что язык C++ состоит из двух основных частей: C++ core language и C++ standard library.


Ну так суть видна из самих определений: "core language" — это именно язык (способ записи, средство выражения и т.п.), а library — это лишь набор стандартных конструкций, ничего не меняющих ни в лексике, ни в синтаксисе, ни в семантике языка. Вообще, делить язык на "core" и "весь язык" — это несколько странно, в стиле рекурсий типа "GNU not UNIX", которые выглядят забавно и изящно, но лишь до тех пор, пока их не пытаются использовать в формальных конструкциях.

NI>Стандартная библиотека C++ вся целиком является неотъемлемой частью языка — так же, как и core language.


С таким определением сразу же возникают коллизии. Например, является ли "Война и мир" составной и неотъемлемой частью русского языка? Является ли квадратный трехчлен составной и неотъемлемой частью алгебры? И является ли конкретный участок конкретной ленты для машины Тьюринга неотъемлемой частью самой машины?
Re[8]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 20.10.18 14:20
Оценка:
Здравствуйте, N. I., Вы писали:

NI>Вот только старый код, использующий promotions, по-тихому сломается.


Чтоб не сломался по-тихому, нужно сегодня объявить, что такое поведение более не комильфо, за полгода добавить в компиляторы новые предупреждения, а через пять-десять лет поменять поведение. За это время все, кто работает над кодом и меняет компиляторы, успеют поправить. Те, кто не меняет компиляторов, ничего не заметят, а те кто меняет, но над кодом не работают, будут сами себе злобные буратины.
Re[12]: Есть ли практический смысл в неявном усечении значен
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 20.10.18 14:43
Оценка:
Здравствуйте, N. I., Вы писали:

NI>>>Если перед тобой появляется куча незнакомого кода, то быстро на глазок определить, нужно ли к нему присобачивать такие опции, может быть несколько затруднительно.

N>>С какого потолка взято про "быстро" "присобачивать"?
NI>С такого, что кому-то придётся тратить время на определение точного набора правил, при котором код делает то, что нужно, а не абы что.

Ещё раз — откуда "быстро на глазок" и всё такое?

NI>>> Кроме того, это для нас добавление в компилятор очередной опции может казаться всего лишь парой пустяков, а для разработчиков компиляторов появление новых опций совместимости — это тот ещё геморрой, т.к. усложняет и без того непростую реализацию, а также её тестирование, покуда во всех допустимых комбинациях они должны между собой дружить. Когда опций много, возможных комбинаций их использования получается ну очень много и тогда можно легко нарваться на какие-нибудь неочевидные corner cases, поскольку уследить за всеми потенциальными взаимодействиями становится просто нереально.


N>>1. Взаимодействовать тут нечему.


NI>Откуда такая уверенность, если ты даже не в курсе, зачем эти promotions нужны?


О, уже начались проезды про некомпетентность собеседника. Прописку скоро спросите?
Кстати, вы явно даже не попытались понять, о чём я говорю — хотя это видно было русским по фоновому.

N>>2. Эти отмазки слышны уже лет 20. "Кто хочет — ищет метод, кто не хочет — ищет причину".

N>>Таки поиск причины не делать.
NI>Ну, да, некоторым людям вообще-то своственно рассматривать pros & cons. Трудности в реализации и поддержки с виду полезной фичи могут перевешивать её достоинства.

Трёп ни о чём.
The God is real, unless declared integer.
Re[7]: Есть ли практический смысл в неявном усечении значений?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 20.10.18 15:02
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

N>>как это надо описать в стандарте, чтобы все согласились.

ЕМ>Навскидку, пара вариантов. Мягкий: запрещено любое неявное усечение, кроме следствий неявного же расширения (например, i8 = i8+i8 разрешено, а i8 = i16 запрещено). Жесткий: запрещено любое неявное усечение, без вариантов.

Ну вот навскидку уже видно, где нужно сделать послабление: правила для констант — чтобы не надо было писать a+(int8_t)4, если a типа int8_t, а сразу писать a+4.
А возможно, ещё несколько специфических случаев попадётся.

N>>Я как раз имею в виду, что в явном варианте конверсия может быть как минимум truncating, checked, saturating...

ЕМ>Это уже детали, которые можно было бы указывать или конструкцией явного преобразования, или явно же задаваемым режимом.

Кому детали, а кому принципиальный элемент реализации. В C/C++ и так много грабель, а все эти UdB только усложняют и без того путаное. Потому я агитирую за контекстно-управляемые режимы. Примеры есть — все эти -fwrapv, -ftrapv; C# — unchecked/checked; Rust — методы типа checked_add; и так далее.
Хотя больше похоже, что продавят просто twoʼs-complement и гарантированное обрезание при усечении, а дальше, скажут, крутитесь сами как хотите.

N>>Ну если у одного и того же софтостроителя в C++ long == int32_t, а в C# long == Int64, а на чуть менее чем всех платформах вокруг тоже long == int64_t, то сомнений нет, где извращение.

ЕМ>У меня таки сомнения. Ибо триада short-int-long устаканивалась во времена, когда 32 разрядов хватало практически на все и, с переходом к 64-разрядным платформам, бОльшую разрядность почти везде стали задавать явно.

32 бита на всё? Хм, даже в 90е годы это было не так. Например, FreeBSD принципиально сделала off_t 64-битным ещё в 2.0 — это чтобы потом не иметь проблем с совместимостью. А всякие Linux & Solaris протормозили с этим и имели неожиданные проблемы.

N>>Особенно учитывая, что в юниксах переход на 64 бита к тому времени состоялся, все грабли пройдены, и "собственная гордость" была тупо нелепа.

ЕМ>Дело не в гордости, а в том, что юниксы устаканивались в первую очередь на RISC'ах, у которых длина команды не зависит от разрядности операндов. А статистика по коду с командами переменной длины показала, что операций с 64-разрядными операндами значительно меньше, чем с 32-разрядными, и в случае родных 64-разрядных и префиксованных 32-разрядных код будет раздуваться чересчур неприлично.

Я не вижу тут принципиальных проблем даже с x86 с его лёгким раздувательством. Всё, для чего было достаточно 32 бит, писалось в int.

EM>>>По этой причине несколько лет назад переделал все переменные, хранившие даже небольшие значения типа размера, в size_t.

N>>Ну так и можно было обойтись int в таких местах.
ЕМ>Раньше там и был int, но все время приходилось ставить явные преобразования, получая ту же длину строки, или смещение в небольшом блоке памяти. Само по себе это не напрягает, но тогда мне казалось, что это еще и бессмысленно с точки зрения оптимальности кода.

Я не про конкретный подход. В общем, понятно.

ЕМ>>>криворуких программистов нужно бить по кривым рукам как можно чаще. И компилятор это сделает эффективнее любого препода или начальника.

N>>Не-а. Он не бьёт, он слишком часто маскирует это.
ЕМ>А вот зачем? Или в комитете по стандартизации криворуких слишком много?

UdB даёт сильно больше возможностей для оптимизации. Там стараются этим пользоваться.
Вот почему при этом перекошенность, что unsigned работает по модулю, а signed не должно переполняться, и что это сохраняют до сих пор — вот это как раз вопрос к возможно... криворукости — вряд ли, а вот альтернативного мышления — таки да.
The God is real, unless declared integer.
Re[9]: Есть ли практический смысл в неявном усечении значений?
От: N. I.  
Дата: 20.10.18 17:49
Оценка:
Евгений Музыченко:

ЕМ>Чтоб не сломался по-тихому, нужно сегодня объявить, что такое поведение более не комильфо, за полгода добавить в компиляторы новые предупреждения, а через пять-десять лет поменять поведение.


Не факт, что это сработает, ведь через пять-десять лет страданий над простынями из явных преобразований сообщество может и передумать
Re[13]: Есть ли практический смысл в неявном усечении значен
От: N. I.  
Дата: 20.10.18 17:50
Оценка: -2
netch80:

N>Ещё раз — откуда "быстро на глазок" и всё такое?


Я не понял суть данного вопроса, однако на все неясные вопросы со словом "откуда" у меня есть универсально правильный ответ: от верблюда!

N>О, уже начались проезды про некомпетентность собеседника.


Не, ну прикольно же: не выяснив, в чём заключается предназначение promotions, уже мечтаем о том, как их выпилить, и наперёд знаем, что никаких негативных последствий не будет. Самоуверенности некоторых диванных аналитиков можно только позавидовать
Re[14]: Есть ли практический смысл в неявном усечении значен
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 20.10.18 17:55
Оценка:
Здравствуйте, N. I., Вы писали:

N>>О, уже начались проезды про некомпетентность собеседника.


NI>Не, ну прикольно же: не выяснив, в чём заключается предназначение promotions,

Ложь-1.

NI> уже мечтаем о том, как их выпилить,

Ложь-2.

NI> и наперёд знаем, что никаких негативных последствий не будет.

Ложь-3.

NI> Самоуверенности некоторых диванных аналитиков можно только позавидовать


А вот тут явная самокритика. Не знаком, но по данной дискуссии — похоже на правду.
Но всё равно конструктива нет. Спасибо за участие, больше не нужно.
The God is real, unless declared integer.
Re[15]: Есть ли практический смысл в неявном усечении значен
От: N. I.  
Дата: 20.10.18 18:11
Оценка: -2
netch80:

NI>>Не, ну прикольно же: не выяснив, в чём заключается предназначение promotions,

N>Ложь-1.

Уже успел нагуглить? Поздравляю

NI>> уже мечтаем о том, как их выпилить,

N>Ложь-2.

Таки передумал?

NI>> и наперёд знаем, что никаких негативных последствий не будет.

N>Ложь-3.

Т.е. признаём, что помимо "за" есть и "против"? Хоть какой-то прогресс.
Re[8]: Есть ли практический смысл в неявном усечении значений?
От: Mystic Artifact  
Дата: 20.10.18 19:29
Оценка:
Здравствуйте, netch80, Вы писали:

ЕМ>>Навскидку, пара вариантов. Мягкий: запрещено любое неявное усечение, кроме следствий неявного же расширения (например, i8 = i8+i8 разрешено, а i8 = i16 запрещено). Жесткий: запрещено любое неявное усечение, без вариантов.

N>Ну вот навскидку уже видно, где нужно сделать послабление: правила для констант — чтобы не надо было писать a+(int8_t)4, если a типа int8_t, а сразу писать a+4.
N>А возможно, ещё несколько специфических случаев попадётся.
Данный вопрос (а именно каков должен быть тип числового литерала) и так решается: как-то же он сейчас выбирает между int, long int и long long int? Собственно ничего не мешает выводить данный тип в более широком диапазоне. Хотя конечно, тут до другого языка уже не далеко.
Re[9]: Есть ли практический смысл в неявном усечении значений?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 21.10.18 06:30
Оценка:
Здравствуйте, Mystic Artifact, Вы писали:

N>>Ну вот навскидку уже видно, где нужно сделать послабление: правила для констант — чтобы не надо было писать a+(int8_t)4, если a типа int8_t, а сразу писать a+4.

N>>А возможно, ещё несколько специфических случаев попадётся.
MA> Данный вопрос (а именно каков должен быть тип числового литерала) и так решается: как-то же он сейчас выбирает между int, long int и long long int?

Но если мы запретим все неявные конверсии, он перестанет так решаться.
А сейчас решается он далеко не идеально. Например, у меня коллега как-то напоролся — 32-битная система, off_t 64-битный, lseek(f, -sizeof(struct data), SEEK_END) ставил совсем не туда, куда надо (смещение получалось положительным). Разобрались, заменили на -(off_t) sizeof(struct data).
Это ситуации такого рода, что пару раз протоптавшись по ним начинаешь замечать, но до того — если не читал источники типа "Внимание, здесь водятся дикие драконы", то приходит совершенно неожиданно.

MA> Собственно ничего не мешает выводить данный тип в более широком диапазоне. Хотя конечно, тут до другого языка уже не далеко.


Ну вот контексты это неплохой метод постепенной миграции к новым правилам. Хотя легаси всё равно останется, и очень тяжёлое.
The God is real, unless declared integer.
Re[8]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 21.10.18 12:13
Оценка: +1
Здравствуйте, netch80, Вы писали:

N>Ну вот навскидку уже видно, где нужно сделать послабление: правила для констант


Проще тип констант выводить из типов других операндов, или подразумеваемого результата выражения.

N>32 бита на всё? Хм, даже в 90е годы это было не так. Например, FreeBSD принципиально сделала off_t 64-битным ещё в 2.0 — это чтобы потом не иметь проблем с совместимостью.


Там, где использовались величины вроде байтового смещения на внешнем носителе, издавна 64-разрядные значения. А по уму, всяких "type_t" должно быть побольше. Например, тип размера строки или структуры разумно было бы сделать отдельным от типа размера произвольного блока памяти — сколько мы во всех программах мира насчитаем строк или структур размером больше 4 Гб?

N>А всякие Linux & Solaris протормозили с этим и имели неожиданные проблемы.


Если бы вместо этого ввели гибкую систему типов — возможно, и не имели бы проблем.

N>Я не вижу тут принципиальных проблем даже с x86 с его лёгким раздувательством.


Арифметико-логический код раздувается на 20-30%. Это уже, как бы, не совсем "легкое".

N>UdB даёт сильно больше возможностей для оптимизации. Там стараются этим пользоваться.


Пока это один и тот же UB. short = int + int полностью аналогично short = short (int + int). Вопрос лишь в том, чтобы первое не могло проскочить незаметно.

N>Вот почему при этом перекошенность, что unsigned работает по модулю, а signed не должно переполняться, и что это сохраняют до сих пор


Где сохраняют? Всю жизнь int работал по модулю, и переполнялся соответственно.
Re[10]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 21.10.18 12:15
Оценка:
Здравствуйте, N. I., Вы писали:

NI>через пять-десять лет страданий над простынями из явных преобразований


Можно пример реального (а не иллюстративного) кода, где замена всех неявных усечений явными могла бы породить "простыни"?
Re[2]: Есть ли практический смысл в неявном усечении значений?
От: _NN_ www.nemerleweb.com
Дата: 21.10.18 12:19
Оценка:
Здравствуйте, netch80, Вы писали:

N>Я вижу пока только один вариант — вводить [[атрибутами]] контексты, где действуют новые правила.

Есть вариант в стиле C#, ключевые слова checked, unchecked:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/checked-and-unchecked

// Checked expression.
auto x = checked(2147483647 + ten);

auto y = unchecked(2147483647 + ten);
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Есть ли практический смысл в неявном усечении значений?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 21.10.18 12:21
Оценка:
Здравствуйте, _NN_, Вы писали:

N>>Я вижу пока только один вариант — вводить [[атрибутами]] контексты, где действуют новые правила.

_NN>Есть вариант в стиле C#, ключевые слова checked, unchecked:

Я на него намекал в том числе. Но ключевые слова наверняка не дадут вводить, а вот пространство атрибутов — оно отдельное, конфликты минимальны, и там это сделать будет сильно проще.
The God is real, unless declared integer.
Re[3]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 21.10.18 12:36
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Есть вариант в стиле C#, ключевые слова checked, unchecked:


Проверки к коду умеют добавлять и некоторые компиляторы C++. Проблема в том, что реальные усечения еще нужно выловить.

Ну и напомню, что самый геморрой вовсе не с проверками, а с количеством вариантов перегруженных/шаблонных функций, которые компилятор считает подходящими для конкретного набора параметров.
Re[9]: Есть ли практический смысл в неявном усечении значений?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 21.10.18 12:37
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

N>>Вот почему при этом перекошенность, что unsigned работает по модулю, а signed не должно переполняться, и что это сохраняют до сих пор

ЕМ>Где сохраняют? Всю жизнь int работал по модулю, и переполнялся соответственно.

Мне слабо верится, что ты не читал эпическую тему
Автор: Кодт
Дата: 18.06.14
про переполнение, и пяток аналогичных. Хотя ты работаешь вроде только с MSVC, там могли это обойти как-то иначе.

N>>Ну вот навскидку уже видно, где нужно сделать послабление: правила для констант

ЕМ>Проще тип констант выводить из типов других операндов, или подразумеваемого результата выражения.

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

N>>32 бита на всё? Хм, даже в 90е годы это было не так. Например, FreeBSD принципиально сделала off_t 64-битным ещё в 2.0 — это чтобы потом не иметь проблем с совместимостью.


ЕМ>Там, где использовались величины вроде байтового смещения на внешнем носителе, издавна 64-разрядные значения. А по уму, всяких "type_t" должно быть побольше. Например, тип размера строки или структуры разумно было бы сделать отдельным от типа размера произвольного блока памяти — сколько мы во всех программах мира насчитаем строк или структур размером больше 4 Гб?


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

N>>А всякие Linux & Solaris протормозили с этим и имели неожиданные проблемы.

ЕМ>Если бы вместо этого ввели гибкую систему типов — возможно, и не имели бы проблем.

Гибкую — это как? off_t как BigInteger?

N>>Я не вижу тут принципиальных проблем даже с x86 с его лёгким раздувательством.

ЕМ>Арифметико-логический код раздувается на 20-30%. Это уже, как бы, не совсем "легкое".

Ты не понял. Код уже раздулся от широких констант, REX префиксов и так далее. Речь о выборе между тем, что long при переходе на 64 бита станет тоже 64, или не станет.
Кто и зачем будет заведомо использовать long для "арифметичеко-логического кода" там, где он идентичен int, но при этом не 64 бита?

N>>UdB даёт сильно больше возможностей для оптимизации. Там стараются этим пользоваться.


ЕМ>Пока это один и тот же UB. short = int + int полностью аналогично short = short (int + int). Вопрос лишь в том, чтобы первое не могло проскочить незаметно.


С тем, что не должно проходить незаметно — я как раз согласен.
The God is real, unless declared integer.
Re[10]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 21.10.18 13:04
Оценка:
Здравствуйте, netch80, Вы писали:

N>Мне слабо верится, что ты не читал эпическую тему
Автор: Кодт
Дата: 18.06.14
про переполнение, и пяток аналогичных.


Не читал — я редко интересуюсь подобными случаями, предпочитаю избегать таких конструкций.

ЕМ>>Если бы вместо этого ввели гибкую систему типов — возможно, и не имели бы проблем.


N>Гибкую — это как? off_t как BigInteger?


Разные типы для разных видов смещений. Смещение члена класса внутри объекта, или символа в строке — это таки несколько иное, чем смещение произвольного байта на произвольном носителе.

N>Код уже раздулся от широких констант, REX префиксов и так далее.


Это отдельно. Я говорю о раздувании кода в одной и той же 64-разрядной функции после замены 32-разрядной арифметики на 64-разрядныю.

N>Кто и зачем будет заведомо использовать long для "арифметичеко-логического кода" там, где он идентичен int, но при этом не 64 бита?


Ну, лично я бы использовал long там, где сейчас еще хватает int, но в будущем уже хватать перестанет. Там, где уже сейчас 32 разряда впритык, лучше сразу закладываться на 64. А еще лучше — вводить отдельный тип для таких значений.
Re[11]: Есть ли практический смысл в неявном усечении значений?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 22.10.18 06:39
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

N>>Мне слабо верится, что ты не читал эпическую тему
Автор: Кодт
Дата: 18.06.14
про переполнение, и пяток аналогичных.

ЕМ>Не читал — я редко интересуюсь подобными случаями, предпочитаю избегать таких конструкций.

Ты-то их можешь избегать сколько угодно. Главное, чтобы они избегали тебя
А с нынешними тенденциями долго сидеть в уютном мирке MSVC, боюсь, не очень получится.

ЕМ>>>Если бы вместо этого ввели гибкую систему типов — возможно, и не имели бы проблем.

N>>Гибкую — это как? off_t как BigInteger?
ЕМ>Разные типы для разных видов смещений. Смещение члена класса внутри объекта, или символа в строке — это таки несколько иное, чем смещение произвольного байта на произвольном носителе.

Понятно. Но я думаю, что аргументы вроде тех, что я приводил, стали причиной того, что это не стали делать.
Да, есть заморочки типа того, что почти все нынешние 64-разрядные платформы не смогут нормально работать при объёме кода больше 2GB. Да, типичное смещение элемента структуры влазит даже не в 32 бита, а в 12, чем пользуется половина RISCʼов. Но всё равно делать из-за этого 1000 разных размеров — смысла не увидели, и я понимаю, почему.
Если где-то он вдруг есть (сложно представить себе такой контекст), там можно и специализированную версию построить.

N>>Код уже раздулся от широких констант, REX префиксов и так далее.

ЕМ>Это отдельно. Я говорю о раздувании кода в одной и той же 64-разрядной функции после замены 32-разрядной арифметики на 64-разрядныю.

А зачем её там так менять, если в 32 всё работает?

N>>Кто и зачем будет заведомо использовать long для "арифметичеко-логического кода" там, где он идентичен int, но при этом не 64 бита?

ЕМ>Ну, лично я бы использовал long там, где сейчас еще хватает int, но в будущем уже хватать перестанет. Там, где уже сейчас 32 разряда впритык, лучше сразу закладываться на 64.

Ну вот именно потому, если 64 желательно, лучше, чтобы long стал 64

EM> А еще лучше — вводить отдельный тип для таких значений.


Тут другая тема. Вводить тип ты можешь сколько угодно, а как ты опознаешь приближение к моменту переполнения или само переполнение, если оно происходит?
Это то, почему я сейчас считаю, что в любом языке, который может быть применён где-то за пределами сверхслабого embedded, допустимым (а в debug и основным по умолчанию) должен быть режим проверки всех операций и генерации ошибки, если что не так. А в небольшом количестве узких мест можно и отменять эти проверки.
The God is real, unless declared integer.
Re[4]: Есть ли практический смысл в неявном усечении значений?
От: _NN_ www.nemerleweb.com
Дата: 22.10.18 07:06
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, _NN_, Вы писали:


_NN>>Есть вариант в стиле C#, ключевые слова checked, unchecked:


ЕМ>Проверки к коду умеют добавлять и некоторые компиляторы C++. Проблема в том, что реальные усечения еще нужно выловить.


ЕМ>Ну и напомню, что самый геморрой вовсе не с проверками, а с количеством вариантов перегруженных/шаблонных функций, которые компилятор считает подходящими для конкретного набора параметров.


При чём здесь перегрузки ?
Для каждого выражения просто задаём желаемое поведение.
А в случае переполнения скажем вызывать std::integer_overflow, который можно переопределить как хотим.

К примеру C#:

using static System.Console;

public class Program
{
    static int f() { unchecked { return int.MaxValue + 10; } } // делаем что хотим
    
    public static void Main()
    {
        int x = checked ( f()*int.MaxValue ); // проверяем и кидаем исключение
        WriteLine(x);
    }
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: Есть ли практический смысл в неявном усечении значени
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 22.10.18 08:53
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>При чём здесь перегрузки ?

_NN>Для каждого выражения просто задаём желаемое поведение.
_NN>А в случае переполнения скажем вызывать std::integer_overflow, который можно переопределить как хотим.
_NN>К примеру C#:

В этом варианте тоже есть проблемы. Знак + для невстроенных типов превращается в op_Add, так?
Но она одна для checked и unchecked контекста. А почему? Получается, для таких типов надо указывать режим в общих свойствах типов, или в типах операций? Неаккуратненько

Уточню: я категорически "за" разделение checked/unchecked; это уже колоссальный прогресс даже в варианте, как сейчас.
Но и тут есть куда двигаться дальше.
The God is real, unless declared integer.
Отредактировано 22.10.2018 8:55 netch80 . Предыдущая версия .
Re[12]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 22.10.18 11:07
Оценка:
Здравствуйте, netch80, Вы писали:

ЕМ>>говорю о раздувании кода в одной и той же 64-разрядной функции после замены 32-разрядной арифметики на 64-разрядныю.


N>А зачем её там так менять, если в 32 всё работает?


Я уже объяснял — надоели преобразования из size_t в UINT и обратно, и одновременно показалось, что 64-разрядные значения будут обрабатываться эффективнее. Обнаружил подвох лишь через некоторое время после того, как все поменял.

N>Это то, почему я сейчас считаю, что в любом языке, который может быть применён где-то за пределами сверхслабого embedded, допустимым (а в debug и основным по умолчанию) должен быть режим проверки всех операций и генерации ошибки, если что не так. А в небольшом количестве узких мест можно и отменять эти проверки.


Согласен. Но при этом хочется возможности и ограничить вольности компилятора, чтобы не вылавливать такие ошибки тестами вместо исправления на ранних этапах.
Re[5]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 22.10.18 11:11
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>При чём здесь перегрузки ?


Это я описал в исходном сообщении.

_NN>Для каждого выражения просто задаём желаемое поведение.


Это для run-time. Я говорю прежде всего о compile-time.
Re[6]: Есть ли практический смысл в неявном усечении значений?
От: _NN_ www.nemerleweb.com
Дата: 22.10.18 11:23
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

_NN>>Для каждого выражения просто задаём желаемое поведение.


ЕМ>Это для run-time. Я говорю прежде всего о compile-time.


Т.е. вам нужны зависимые типы ?
Этого боюсь точно не добавят.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: Есть ли практический смысл в неявном усечении значени
От: _NN_ www.nemerleweb.com
Дата: 22.10.18 11:24
Оценка:
Здравствуйте, netch80, Вы писали:

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


_NN>>При чём здесь перегрузки ?

_NN>>Для каждого выражения просто задаём желаемое поведение.
_NN>>А в случае переполнения скажем вызывать std::integer_overflow, который можно переопределить как хотим.
_NN>>К примеру C#:

N>В этом варианте тоже есть проблемы. Знак + для невстроенных типов превращается в op_Add, так?

N>Но она одна для checked и unchecked контекста. А почему? Получается, для таких типов надо указывать режим в общих свойствах типов, или в типах операций? Неаккуратненько
Почему это будут две перегрузки ?
Есть только одна.
Что внутри там делает это дело функции.
Хочет будет внутри checked, хочет нет.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[7]: Есть ли практический смысл в неявном усечении значени
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 22.10.18 12:06
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Почему это будут две перегрузки ?

_NN>Есть только одна.
_NN>Что внутри там делает это дело функции.
_NN>Хочет будет внутри checked, хочет нет.

И как оно внутри узнает про выбранный режим (checked/unchecked)? Он в C# синтаксический, а не где-то в опциях текущей нитки или аналогичном месте.
Вот см. таблицу — в unchecked сгенерируется add, а в checked — add.ovf или add.ovf.un. Но это делает сам компилятор, у него под это специальные заточки есть.
Как чужой функции узнать этот контекст?
The God is real, unless declared integer.
Re[7]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 22.10.18 12:12
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Т.е. вам нужны зависимые типы ?


Не. Мне нужно, чтобы в ситуации, когда есть версии перегруженной функции для наборов параметров, скажем, (int, int) и (long, long), и есть вызов с фактическими параметрами (int, long), компилятор не изображал философа, утверждая, что он в равной степени мог бы применить и то, и другое.
Re[8]: Есть ли практический смысл в неявном усечении значени
От: _NN_ www.nemerleweb.com
Дата: 22.10.18 12:16
Оценка:
Здравствуйте, netch80, Вы писали:

N>И как оно внутри узнает про выбранный режим (checked/unchecked)? Он в C# синтаксический, а не где-то в опциях текущей нитки или аналогичном месте.

N>Вот см. таблицу — в unchecked сгенерируется add, а в checked — add.ovf или add.ovf.un. Но это делает сам компилятор, у него под это специальные заточки есть.
N>Как чужой функции узнать этот контекст?
Узнает где ?
checked/unchecked не идёт дальше функции:

В настройками по умолчанию (unchecked) этот код выводит -4
using static System.Console;

public class Program
{
    static int Q()
    {
        int i = int.MaxValue;
        int j = 2;
        return i * j;
    }
    
    static int F()
    {
       return Q() * 2;
    }
    
    public static void Main()
    {
        checked
        {
            int i = F();
            WriteLine(i);
        }
    }
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[8]: Есть ли практический смысл в неявном усечении значений?
От: _NN_ www.nemerleweb.com
Дата: 22.10.18 12:18
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, _NN_, Вы писали:


_NN>>Т.е. вам нужны зависимые типы ?


ЕМ>Не. Мне нужно, чтобы в ситуации, когда есть версии перегруженной функции для наборов параметров, скажем, (int, int) и (long, long), и есть вызов с фактическими параметрами (int, long), компилятор не изображал философа, утверждая, что он в равной степени мог бы применить и то, и другое.

Т.е. просто запретить преобразование long => int ?
В C# примерно так и есть:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/implicit-numeric-conversions-table
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[9]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 22.10.18 12:20
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Т.е. просто запретить преобразование long => int ?


Только неявное. И все остальные, при которых могут быть потеряны значащие разряды.

_NN>В C# примерно так и есть:


Очень рад, но мне-то нужно в C++.
Re[10]: Есть ли практический смысл в неявном усечении значений?
От: _NN_ www.nemerleweb.com
Дата: 22.10.18 12:27
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:


_NN>>В C# примерно так и есть:


ЕМ>Очень рад, но мне-то нужно в C++.

Тут варианта два.
Один протолкнуть в стандарт, там через https://stdcpp.ru/ или ещё как-нибудь.

Второй в компилятор добавить опцию ловить такое поведение.
Если ещё такого нет, то можно предложить.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[9]: Есть ли практический смысл в неявном усечении значений?
От: N. I.  
Дата: 22.10.18 18:40
Оценка:
Евгений Музыченко:

ЕМ>Проще тип констант выводить из типов других операндов, или подразумеваемого результата выражения.


Всех констант? Суффиксы литералов 1U, 1L, 1UL, и т.д. тоже проигнорируем? И что насчёт constexpr переменных?
Re[11]: Есть ли практический смысл в неявном усечении значений?
От: N. I.  
Дата: 22.10.18 18:45
Оценка:
Евгений Музыченко:

ЕМ>Можно пример реального (а не иллюстративного) кода, где замена всех неявных усечений явными могла бы породить "простыни"?


Лениво искать. Последствия выпиливания integral promotions тоже интересные, т.к. promotions влияют на тип выражения и его результат. Получается, что во время предлагаемого переходного периода нам и компиляторам надо будет руководствоваться сразу двумя наборами правил и не допускать ситуаций, когда одно и то же выражение имеет разный смысл или даёт разные результаты в зависимости от того, какие правила применяются — с promotions или без них. Чтобы получать соответствующую диагностику от компилятора, придётся не просто убирать promotions, на которые мы рассчитываем, но ещё и демонстрировать компилятору, что некоторые promotions на самом деле ни на что не влияют.

std::uint8_t x, y;
...
int z = x + y;

Даже если мы точно знаем, что в этом конкретном месте x + y всегда меньше или равно 255, компилятору это может быть неизвестно, и тогда потребуется что-то вроде

int z = std::uint8_t(x + y);

чтобы показать ему, что мы не пытаемся использовать расширенный диапазон для вычисления суммы.
Re[8]: Есть ли практический смысл в неявном усечении значений?
От: N. I.  
Дата: 22.10.18 18:47
Оценка:
Евгений Музыченко:

ЕМ>Мне нужно, чтобы в ситуации, когда есть версии перегруженной функции для наборов параметров, скажем, (int, int) и (long, long)


Зачем нужны такие перегрузки? Чем не устраивает один универсальный шаблон, работающий с любой комбинацией?

ЕМ>и есть вызов с фактическими параметрами (int, long), компилятор не изображал философа, утверждая, что он в равной степени мог бы применить и то, и другое


Можно заставить его выбрать одну из таких функций, используя шаблон-переходник:

#include <iostream>
#include <type_traits>

void f(int, int, int) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
void f(long, long, long) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
void f(long long, long long, long long) { std::cout << __PRETTY_FUNCTION__ << std::endl; }

template <class T1, class T2, class T3>
    void f(T1 x1, T2 x2, T3 x3)
{
    using T = std::common_type_t<int, T1, T2, T3>;
    static_assert(!std::is_same_v<T, T1> || !std::is_same_v<T, T2> || !std::is_same_v<T, T3>, "can't delegate the call");
    f(T(x1), T(x2), T(x3));
}

int main()
{
    f('1', '1', short(1));
    f(1, 1, 1);
    f(1L, 1L, 1L);
    f(1, 1L, 1);
    f(1, 1L, 1LL);
    /// f(__int128(1), 1, 1); // triggers the static_assert
 }

https://wandbox.org/permlink/9AXpi3yl9DTdhv4d
Re[10]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.10.18 14:52
Оценка:
Здравствуйте, N. I., Вы писали:

ЕМ>>Проще тип констант выводить из типов других операндов, или подразумеваемого результата выражения.


NI>Всех констант? Суффиксы литералов 1U, 1L, 1UL, и т.д. тоже проигнорируем?


Зачем их игнорировать? Выводить имеет смысл, если константа указана без суффикса или явного приведения.
Re[9]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.10.18 16:23
Оценка:
Здравствуйте, N. I., Вы писали:

NI>Зачем нужны такие перегрузки? Чем не устраивает один универсальный шаблон, работающий с любой комбинацией?


Некоторые варианты комбинаций параметров оптимизированы (ассемблерными вставками для 32-разрядных платформ).

NI>Можно заставить его выбрать одну из таких функций, используя шаблон-переходник:


Вот я и говорю, что кривизну реализации перегрузки можно исправить лишь костылем из нетипичного применения шаблонов. При том, что common_type в std появился относительно недавно (в MS VS 2008, например, его нет), поэтому необходимо либо выдирать и переносить, либо городить свою реализацию.

Вообще, такое впечатление, что с некоторых пор разработчики языка решили свалить преодоление любых недостатков и косяков на метапрограммирование, хоть бы и в крайне извращенных формах.
Re[11]: Есть ли практический смысл в неявном усечении значений?
От: N. I.  
Дата: 23.10.18 19:32
Оценка:
Евгений Музыченко:

NI>>Всех констант? Суффиксы литералов 1U, 1L, 1UL, и т.д. тоже проигнорируем?


ЕМ>Зачем их игнорировать?


Не знаю, я просто пытаюсь понять идею в деталях. На данный момент тип целочисленного литерала определяется значением литерала, суффиксом и используемой системой счисления. Если тип литерала ещё контекстно-зависимым сделать, то, для меня, например, это не выглядит, как упрощение.
Re[12]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 24.10.18 11:47
Оценка: +2
Здравствуйте, N. I., Вы писали:

NI>На данный момент тип целочисленного литерала определяется значением литерала, суффиксом и используемой системой счисления. Если тип литерала ещё контекстно-зависимым сделать, то, для меня, например, это не выглядит, как упрощение.


А для чего литералу без специальных префиксов/суффиксов непременно иметь собственный тип? Почему это не может быть просто минимальный по разрядности тип, в котором литерал может быть однозначно представлен? Тогда и "char c = 10" не потребовало бы явного или неявного приведения, которое тут совершенно излишне.
Re[13]: Есть ли практический смысл в неявном усечении значений?
От: N. I.  
Дата: 24.10.18 20:58
Оценка:
Евгений Музыченко:

ЕМ>А для чего литералу без специальных префиксов/суффиксов непременно иметь собственный тип?


Когда все выражения имеют какой-то тип, это позволяет применять к ним одинаковые правила. Например, шаблону функции всё равно, что ты ему передашь — литерал 1 или результат какой-нибудь функции, возвращающей rvalue типа int. А вот с магическими конструкциями вроде {0, 1}, которые выражениями не являются, всё куда печальнее: с шаблонами они плохо дружат (дедукция не работает) и правила разрешения перегрузки такие, что стандартизаторы сами в них долго путались.

ЕМ>Почему это не может быть просто минимальный по разрядности тип, в котором литерал может быть однозначно представлен?


Вопрос в том, насколько это удобно. Собственно, сейчас выбор типа на основе значения тоже имеется, только ряд рассматриваемых типов начинается с int. Если значение десятичного литерала без суффикса не вмещается в int, то дальше рассматривается long int, а если и long int не хватает, то следующим кандидатом будет long long int.

ЕМ>Тогда и "char c = 10" не потребовало бы явного или неявного приведения, которое тут совершенно излишне.


Т.е. литерал 10 сам по себе должен иметь тип char? А почему не signed char? Как бы там ни было, выбор в пользу любого из этих типов сделает необходимым преобразование к другому.
Re[9]: Есть ли практический смысл в неявном усечении значени
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 25.10.18 05:43
Оценка:
Здравствуйте, _NN_, Вы писали:

N>>И как оно внутри узнает про выбранный режим (checked/unchecked)? Он в C# синтаксический, а не где-то в опциях текущей нитки или аналогичном месте.

N>>Вот см. таблицу — в unchecked сгенерируется add, а в checked — add.ovf или add.ovf.un. Но это делает сам компилятор, у него под это специальные заточки есть.
N>>Как чужой функции узнать этот контекст?
_NN>Узнает где ?
_NN>checked/unchecked не идёт дальше функции:

Ну вот и у тебя в функции написано что-то типа

  Buka Foo(Buka a, Buka b) {
    return checked(a + b);
  }


"+" переопределена для Buka, но сделать раздельное переопределение для checked и unchecked нельзя.
А для int — сделано из коробки, операции будут разные. Завидно
The God is real, unless declared integer.
Re[14]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 25.10.18 16:51
Оценка:
Здравствуйте, N. I., Вы писали:

NI>А вот с магическими конструкциями вроде {0, 1}, которые выражениями не являются, всё куда печальнее: с шаблонами они плохо дружат (дедукция не работает) и правила разрешения перегрузки такие, что стандартизаторы сами в них долго путались.


На мой взгляд, следовало бы выбирать минимально подходящие по разрядности/знаковости варианты перегрузки, в сомнительных случаях выдавая предупреждения (которые можно подавить). Кому надо — всегда может указать тип явно, это делается просто и быстро. А вот в той ситуации, что существует, нет не только простого и быстрого способа, но и адекватного тоже — только шаманские.

NI>Т.е. литерал 10 сам по себе должен иметь тип char? А почему не signed char?


Так char по умолчанию signed.
Re[15]: Есть ли практический смысл в неявном усечении значений?
От: aa_unique  
Дата: 25.10.18 17:12
Оценка:
NI>>Т.е. литерал 10 сам по себе должен иметь тип char? А почему не signed char?

ЕМ>Так char по умолчанию signed.


Насколько я помню, именно с char'ом там всё хуже, то ли по умолчанию он может быть как signed, так и unsigned, то ли вообще char, signed char и unsigned char — это три разных типа.
Вот, например: https://ideone.com/fFKGaa
Re[15]: Есть ли практический смысл в неявном усечении значений?
От: N. I.  
Дата: 25.10.18 19:54
Оценка:
Евгений Музыченко:

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


А как определить, какой случай сомнительный? Например, некоторые функции, формирующие text output, вполне могут решить, что, подсунув значение типа char/signed char/unsigned char, ты хочешь добавить в результирующий текст символ, а не строковое представление числа, в то время как значение типа int они интерпретируют как число.

ЕМ>Кому надо — всегда может указать тип явно, это делается просто и быстро. А вот в той ситуации, что существует, нет не только простого и быстрого способа


Дык ты и сейчас можешь явные преобразования делать — просто и быстро. В чём проблема?

NI>>Т.е. литерал 10 сам по себе должен иметь тип char? А почему не signed char?


ЕМ>Так char по умолчанию signed.


Знаковость char-а является implementation-defined, и, насколько я помню, есть реализации, где char по умолчанию беззнаковый. В GCC, Clang и VC++ знаковость char-а можно регулировать ключиками. В любом случае char, signed char и unsigned char — эти три разных типа, и если представления char и signed char полностью совпадают, перевод значения char в signed char или наоборот всё равно считается преобразованием, которое, кстати, хуже, чем преобразование в int. Например, тут

#include <iostream>

void f(signed char) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
void f(unsigned char) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
void f(int) { std::cout << __PRETTY_FUNCTION__ << std::endl; }

int main()
{
    f('c');
}

предпочтение будет отдано f(int).

И покуда для char-ов уже и так есть символьные литералы, зачем ещё обычные целочисленные литералы char-ами делать? Чтоб потом ловить лулзы при переводах в текстовое представление?
Re: Есть ли практический смысл в неявном усечении значений?
От: andyp  
Дата: 29.10.18 17:11
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Есть ли какое-то практическое обоснование тому, что в C++ до сих разрешено неявное усечение значений (например, int до char)?


Только что у Джосаттиса встретил

char a = 'a';
char b = 'b';
char c1 = a + 1; // promotion of operands to int, then narrowing
char c2 = a + b; // promotion, then narrowing


Promotion без narrowing — гарантированный адок будет — каст на каждой строчке арифметики. Так что, narrowing — обратная сторона promotion имхо. Если уж менять это поведение, то только вместе с promotion — определить арифметику для всех комбинаций фундаментальных типов. Но это приведет к тому, что очень большая часть уже написанного кода станет по другому работать.
Re[16]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 30.10.18 05:46
Оценка:
Здравствуйте, N. I., Вы писали:

NI>Например, некоторые функции, формирующие text output, вполне могут решить, что, подсунув значение типа char/signed char/unsigned char, ты хочешь добавить в результирующий текст символ, а не строковое представление числа, в то время как значение типа int они интерпретируют как число.


Ну так символ в апострофах имеет тип char, а коли надо задать символ кодом — нетрудно написать char (0x15).

NI>Дык ты и сейчас можешь явные преобразования делать — просто и быстро. В чём проблема?


В том, что это невозможно (или откровенно коряво) делать при обращении к перегруженным функциям из шаблонных.

NI>И покуда для char-ов уже и так есть символьные литералы, зачем ещё обычные целочисленные литералы char-ами делать? Чтоб потом ловить лулзы при переводах в текстовое представление?


Ладно, пусть числовые константы начинаются с int. Но тогда неявное, тихое преобразование их в char опять-таки некорректно, да и так часто такие конструкции встречаются, чтобы экономить на них явные преобразования.
Re[2]: Есть ли практический смысл в неявном усечении значений?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 30.10.18 05:52
Оценка:
Здравствуйте, andyp, Вы писали:

A>
A>char a = 'a';
A>char b = 'b';
A>char c1 = a + 1; // promotion of operands to int, then narrowing
A>char c2 = a + b; // promotion, then narrowing
A>


A>Promotion без narrowing — гарантированный адок будет — каст на каждой строчке арифметики.


А кто в здравом уме станет писать много подобных строчек?
Re[17]: Есть ли практический смысл в неявном усечении значений?
От: N. I.  
Дата: 30.10.18 12:05
Оценка:
Евгений Музыченко:

NI>>Например, некоторые функции, формирующие text output, вполне могут решить, что, подсунув значение типа char/signed char/unsigned char, ты хочешь добавить в результирующий текст символ, а не строковое представление числа, в то время как значение типа int они интерпретируют как число.


ЕМ>Ну так символ в апострофах имеет тип char, а коли надо задать символ кодом — нетрудно написать char (0x15).


Я не понял, какое отношение это имеет к описанной проблеме. Речь шла про изменение типа целочисленных литералов, от которого может зависеть интерпретация их значения.

#define MAJOR_VERSION 42
#define MINOR_VERSION 1

#include <iostream>

void print_version()
{
    std::cout << "Version: " << MAJOR_VERSION << "." << MINOR_VERSION << std::endl;
}

int main()
{
    print_version();
}

Полагаю, излишне объяснять, как изменится вывод этой программы, если 42 и 1 заменить на char(42) и char(1) соответственно. Если тип литералов 42 и 1 изменить с int на char, эффект будет такой же.

NI>>Дык ты и сейчас можешь явные преобразования делать — просто и быстро. В чём проблема?


ЕМ>В том, что это невозможно (или откровенно коряво) делать при обращении к перегруженным функциям из шаблонных.


А как так получается, что эти хитрые комбинации аргументов разных типов возникают внутри шаблона? И нельзя ли фактические аргументы шаблона задать так, чтоб внутри него преобразования не понадобились?

ЕМ>Ладно, пусть числовые константы начинаются с int. Но тогда неявное, тихое преобразование их в char опять-таки некорректно, да и так часто такие конструкции встречаются, чтобы экономить на них явные преобразования.


Ежели так сильно хочется иметь арифметику без неявных narrowing и promotions, можешь реализовать всю нужную тебе логику таких вычислений в специальных классах-обёртках над integers. Код будет выглядеть похоже на обычный:

int_<8> x = 42_i8;        // OK: int_<8> -> int_<8>
int_<8> y1 = x + 1_i8;    // OK: int_<8> -> int_<8>
int_<16> y2 = x + 1_i8;   // OK: int_<8> -> int_<16>
int_<16> y3 = x + 1_i16;  // OK: int_<16> -> int_<16>
int_<8> y4 = x + 1_i16;   // error: int_<16> -> int_<8>
int_<8> y5(x + 1_i16);    // OK: explicit int_<16> -> int_<8>

Заодно можно определить свои правила для смешанных signed и unsigned аргументов и проверку переполнения сделать.
Re[3]: Есть ли практический смысл в неявном усечении значений?
От: andyp  
Дата: 30.10.18 18:06
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>А кто в здравом уме станет писать много подобных строчек?


Пишут же Да и сам грешен, бывает пишу
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.