2016-01-03 2 views
11

В C и C++ поведение знакового целочисленного переполнения или нижнего потока не определено.Содержит ли спецификации C# и Java одно и то же поведение при переполнении целых чисел?

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


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

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

И:

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


От C# спецификации, мы имеем:

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


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

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

+0

Если поведение хорошо определено для языка, почему он должен отличаться между платформами ?! – JimmyB

+1

@HannoBinder Когда я использую термин * четко определенный *, я имею в виду его в отличие от * undefined * - ни на Java, ни на C# он не определен.Но я до сих пор не понимаю, специфицирует ли спецификация портативных результатов или просто оставляет поведение как * определяемое реализацией *. –

+0

Если вы посмотрите на * Работа с 32-разрядными Целочисленными значениями без десятичного разряда * в документации [System.Int32] (https://msdn.microsoft.com/en-us/library/system.int32.aspx), вы можете см., что, по крайней мере, для ints, представление одинаково для всех платформ. Я подозреваю, что это то же самое для других типов. –

ответ

1

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

В .NET существуют примитивные типы, определенные CLR, и они также обертываются различными классами и псевдонимами в зависимости от языка. См. Common Language Specification - esp. Common Type Systtem.

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

Смежные вопросы