Указывают ли спецификации C # и Java одинаковое поведение при переполнении целого числа со знаком?

В C и C ++ поведение подписанного целочисленного переполнения или потери значимости не определено.

В Java и C # (неконтролируемые контексты) поведение кажется до некоторой степени определенным.


Из спецификации Java мы имеем:

Целочисленные операторы никоим образом не указывают на переполнение или потерю значимости.

А также:

В языке программирования Java используется представление целых чисел с дополнением до двух [...]


Из спецификации C # у нас есть:

[...] В неконтролируемом контексте переполнение игнорируется, а любые старшие биты, не подходящие для целевого типа, отбрасываются.


Протестировав оба, я получил ожидаемый общий результат. Судя по формулировке спецификаций, у меня возникает ощущение, что в Java результат переносим (потому что язык требует представления с двумя дополнениями), в то время как C # может иметь или не иметь этого результата (поскольку он, похоже, не указывает представление - только то, что отбрасываются биты более высокого порядка).

Итак, гарантируют ли обе языковые спецификации одинаковое поведение на всех платформах (только с разными формулировками)? Или они просто совпадают друг с другом в моем тестовом примере (на x86 и под Sun JRE и Microsoft .NET), но теоретически могут отличаться на других архитектурах или реализациях?


person Theodoros Chatzigiannakis    schedule 03.01.2016    source источник
comment
Если поведение четко определено для языка, почему оно должно различаться между платформами ?!   -  person JimmyB    schedule 03.01.2016
comment
@HannoBinder Когда я использую термин четко определенный, я имею в виду его в отличие от undefined - ни в Java, ни в C # он не определен. Но я до сих пор не понимаю, прописаны ли в спецификации переносимые результаты или просто оставлено поведение как определенное реализацией.   -  person Theodoros Chatzigiannakis    schedule 03.01.2016
comment
Если вы посмотрите на Работа с 32-разрядными недесятичными целыми числами в Документация по System.Int32 вы можете видеть, что, по крайней мере, для целых чисел представление одинаково на всех платформах. Я подозреваю, что то же самое и с другими типами.   -  person Fernando Matsumoto    schedule 03.01.2016
comment
Даже с комплиментом 2 вы можете усилить насыщенность (вместо обертывания) и вернуть наивысшее целое число только в комплименте 2. Так что я не понимаю, почему это подразумевает переносимость.   -  person Reinstate Monica    schedule 07.01.2016


Ответы (1)


В Java переносимость обеспечивается Спецификацией языка Java, которая устанавливает все правила для примитивного типа intbeing 32-битное целое число с дополнением до 2. Затем сама стандартная библиотека реализует класс Integer, который обертывает значение int и добавляет несколько удобных методов, но по сути то же самое в том, что касается диапазона и переполнения.

В .NET есть примитивные типы, определенные CLR, и они тоже обертываются разными классами и псевдонимами в зависимости от языка. См. Спецификацию общего языка - особенно. Система общего типа.

Итак, чтобы ответить на ваш вопрос, в Java код переносится, что обеспечивается спецификацией языка и реализацией JVM. В .NET (поскольку CLR запускает также код C ++, который, в свою очередь, может быть несовместим с CLS, работая на уровне, близком к железу), вы должны убедиться, что ваш код переносится, сделав его Совместимость с CLS. Хорошая новость заключается в том, что использование int и / или System.Int32 делает вас совместимым с CLS, а значит, переносимым.

person diginoise    schedule 02.02.2016