Содержит ли спецификации С# и 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.