Содержит ли спецификации С# и Java одно и то же поведение при переполнении со знаком целого?
В C и С++ поведение сглаженного целочисленного переполнения или нижнего потока undefined.
В Java и С# (непроверенные контексты) поведение, по-видимому, определяется в определенной степени.
Из спецификации Java мы имеем:
Целочисленные операторы никак не указывают на переполнение или недополнение.
и
Язык программирования Java использует двухзначное представление для целых чисел [...]
Из спецификации С# мы имеем:
[...] В неконтролируемом контексте переполнения игнорируются, а любые старшие разряды, не соответствующие типу назначения, отбрасываются.
Проверяя оба, я получил ожидаемый результат обхода. Судя по формулировке спецификаций, у меня возникает ощущение, что в Java результат переносимый (потому что язык требует представления с двумя дополнениями), в то время как С# может иметь или не иметь такого результата (поскольку он не указывает на представление - только то, что биты более высокого порядка отбрасываются).
Таким образом, оба языка гарантируют одинаковое поведение на всех платформах (только с другой формулировкой)? Или они просто оказываются одинаковыми друг с другом в моем тестовом примере (на x86 и под Sun JRE и Microsoft.NET), но теоретически могут отличаться в других архитектурах или реализациях?
Ответы
Ответ 1
В Java переносимость обеспечивается Спецификацией Java Language, которая заявляет, что все правила вокруг примитивного типа int
подписываются на 32bit 2 integer. Тогда сама стандартная библиотека реализует класс Integer
, который обертывает значение int
и добавляет несколько удобных методов, но по существу тот же, что и диапазон и переполнение.
В .NET существуют примитивные типы, определенные CLR, и они также обертываются разными классами и псевдонимами в зависимости от языка. См. Общая спецификация языка - особенно. Common Type Systtem.
Итак, чтобы ответить на ваш вопрос, в Java, код переносится, как это предусмотрено в реализации Language Spec и JVM. В .NET (поскольку CLR запускает также код С++, который, в свою очередь, не может быть CLS-совместимым, работающим ближе к уровню железа), вы должны убедиться, что ваш код переносим, сделав его Соответствие CLS. Хорошая новость заключается в том, что использование int
и/или System.Int32
делает вас совместимым с CLS, ergo portable.