Поделиться через


Общие вопросы использования Visual C++ ARM

Тот же исходный код Visual C#, C-++ может выдавать разные результаты в архитектуре ARM, что создается в архитектурах x86 или x64.

Источников проблем миграции

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

  • Не определенное расширение функциональности
    Расширение функциональности, стандарт C и C-++ не определяет, вызываемое операцией, которая не имеет не следует результат- для примера, при преобразовании значения с плавающей запятой в целое число без знака, или сдвигая значение несколькими позиций, отрицательное или превышает число битов в своем повышенным уровнем типа.

  • Определенное поведение реализацией
    Расширение функциональности стандарт C, C-++ требует поставщика компилятора определяет документ.Программа может безопасно полагаться на определенное реализацией поведении, даже если управляемая куча может не будет.Примеры реализации определенного поведения включают размеры встроенных типов данных и требований к выравнивания.Пример операции, может быть влияют на определенное реализацией поведением получить переменное число аргументов.

  • Неопределенное расширения функциональности
    Расширение функциональности то стандарт C намеренно не найдены. детерминистским.Хотя расширение функциональности считается не детерминистским, определяемые вызовы неспецифицированного расширения функциональности определяются реализацией компилятора.Однако общего требования для поставщика компилятора предопределить результат или обеспечить соответствующее расширение функциональности между соответствующими вызовами и общего требования для документации.Пример неспецифицированного расширения функциональности порядок, в котором подводн-выражение-, включающих вычисляются аргументы функции вызова.

Другие проблемы миграции можно отнесут в различий в оборудования между ARM и x86 или x64 архитектурами, взаимодействующих со стандартом C C-++ по-разному.Например, модель сильной памяти архитектуры x86 и x64 ( volatile- уточненные переменные некоторые дополнительные свойства, которые использовались для упрощения некоторых типов взаимодействия между потоками в прошлом.Однако модель архитектуры памяти ARM слабая не поддерживает это используется стандартный C и C-++ требует его.

Важное примечаниеВажно

Хотя volatile получает некоторые свойства, которые можно использовать для реализации ограниченные формы взаимодействия между потоками в x86 и x64, такие дополнительные свойства не достаточны для реализации взаимодействия между потоками в целом.Стандарт C C-++ рекомендованные, чтобы одно сообщение было реализовано с помощью соответствующих примитивы синхронизации вместо.

Поскольку две платформы могут быть выражены эти типы расширений функциональности по-разному, перенос программное обеспечение между платформами может быть нелегко и ошибка- прональн, если оно зависит от расширения функциональности конкретной платформы.Хотя многие из этих типов расширения функциональности можно отслеживать и могут быть оно, полагаться на их по крайней мере не будет, и в случаях неопределенного или неспецифицированного расширения функциональности, также ошибка.Даже расширение функциональности, процитировано в этом документе не должен быть включен (и может измениться в будущих реализациях инструментальным или ЦП.

Проблемы с миграцией примера

Оставшаяся часть этого документа описывается другое расширение функциональности этих элементов языка C C-++ может выдавать разные результаты в разных платформах.

Преобразование с плавающей запятой в целое число без знака

В архитектуре ARM, преобразование плавающей запятой в 32 разрядному целое число насыщает у ближайших значение, если представляет целое число с плавающей запятой вне диапазона, целое число может представлять.В архитектурах x86 и x64, использование оболочки преобразования вокруг целое число, если удаляется подпись, или задано значение -2147483648, если знаковое целое число.Ни одно из этих архитектур непосредственно поддерживают преобразование плавающей запятой с более низким целочисленным типам; вместо этого преобразования выполняются до 32 бита, и результаты усекаются в более редко размера.

Для архитектуры ARM насыщенность и усечение сочетания из означают, что преобразования в типы без знака правильно насыщает меньшие беззнаковые типы при насыщает 32 8-разрядное целое число, но обеспечивается усечения значений, которые больше нижней тип может представлять, но слишком маленький, чтобы насытить полностью 32 8-разрядное целое число.Преобразование также насыщает правильно для 32 разрядных знаковых целых чисел, но усечение насыщенный, знаковые целые числа приводит к -1 для положительн- насыщенных значений и 0 для отрицательн- насыщенных значений.Преобразование в более редко знаковому целому числу предоставляет усечения, невозможно с точностью предсказать.

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

Эти платформы также отличаются, как они обрабатывают преобразование Nan (не число) к целочисленным типам.На ARM, Nan преобразования к 0x00000000; для платформы x86 и x64, оно может быть преобразовано в значение 0x80000000.

С плавающей запятой преобразование можно использовать только, если известно, что значения в диапазоне целочисленного типа, его преобразование.

Расширение функциональности оператора Shift (<< >>)

В архитектуре ARM, значение можно сдвигать влево или вправо до 255 бит перед шаблон начинает итерации.В архитектурах x86 и x64, шаблон повторен на каждой многократному чтению 32 источник шаблона не будет 64 разрядная переменной; в этом случае шаблон повторит на каждой многократному чтению на 64 x64 и каждой многократному чтению 256 для платформы x86, где используется реализация программного обеспечения.Например, для 32 разрядной переменной, которая имеет значение 1 сдвигало налево 32 позициями в ARM результат 0 на 1, результат x86 и x64 на результат также 1.Однако если источник значения 64 разрядная переменная, результат на всех платформах 3 4294967296, а значение "не создает вокруг" до тех пор, пока она не будет сдвигать в позиции 64 x64 или 256 позиций на ARM и x86.

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

Переменная расширение функциональности аргументов функций ()

В архитектуре ARM, параметры переменной из списка аргументов, передаваемых в стек определяется выравнивание.Например, 64 - параметр выравнивается с 64 разрядной границе.Для платформы x86 и x64 аргументы, передаваемые в стек выравнивание и не могут повлиять на пакет.Это различие может вызвать функцию printf variadic как чтение адреса памяти запланированные как заполнение на ARM, если ожидается макет переменной списка аргументов точно не совпадает, даже если он может работать для подмножества некоторых значений в архитектурах x86 или x64.Рассмотрим следующий пример.

// notice that a 64-bit integer is passed to the function, but '%d' is used to read it.
// on x86 and x64 this may work for small values because %d will “parse” the low-32 bits of the argument.
// on ARM the calling convention will align the 64-bit value and the code will print a random value
printf("%d\n", 1LL);   

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

// CORRECT: use %I64d for 64-bit integers
printf("%I64d\n", 1LL);

Порядок вычисления аргумента

Поскольку ARM, x86, x64 и другие процессоры, поэтому они могут представлять различные требования к реализации компилятора, а также различные возможности для оптимизации.Вследствие этого вместе с другими факторами, такими как параметры соглашения о вызовах и оптимизации, компилятор может оценить аргументы функции в другом порядке на различных архитектурах, или другие факторы изменится.Это может привести к расширению функциональности приложения, основана на алгоритме оценки изменение неопределенным.

Этот тип ошибки может произойти, если аргументы функции имеют побочные эффекты, которые оказывают влияние на другие аргументы функции в одном вызове.Обычно этот тип зависимости делать во избежание, но иногда может быть становится бледным зависимостями, которые трудно discern или перегрузкой оператора.Рассмотрим пример кода:

  handle memory_handle;

  memory_handle->acquire(*p);

Это кажется чётким, но, если -> и * перегруженные операторы, этот код преобразуется в элемент, имеет следующий вид:

  Handle::acquire(operator->(memory_handle), operator*(p));

И если зависимость между operator->(memory_handle) и operator*(p), то код может полагаться на алгоритме оценки, даже если исходный код выглядит как в ней нет возможная зависимость.

реакция на событие по умолчанию ключевое слово volatile

Поддержки компилятора C Microsoft C-++ 2 различных интерпретации квалификатора испаряющего хранилища, можно задать с помощью параметров компилятора.Параметр /volatile:ms выделяет семантика расширенная Майкрософт испаряющая, гарантирует строгой упорядочение, как обычная регистр для x86 и x64 в компиляторе Майкрософт модели из-за сильной памяти для тех архитектуры.Параметр /volatile:iso выделяет семантика строгого C, C-++ стандартная испаряющая не гарантирует порядок строгой.

В архитектуре ARM, по умолчанию используется значение /volatile:iso, поскольку процессоры ARM имеют слабо упорядоченной модели памяти, а поскольку программное обеспечение ARM не имеет старую версию полагаться на выдвинутой семантике /volatile:ms и не выполняет обычно интерфейс с программным обеспечением, обеспечивающее.Однако она по-прежнему иногда удобно или даже необходимо, чтобы компилировать программа вооружения для использования выдвинутой семантики.Например, может быть слишком больших затрат ресурсов на порт программы для использования семантики C или C-++ ISO, программное обеспечение драйвера может следовать семантике в традиционной функции правильно.В таких случаях можно использовать параметр /volatile:ms. однако для повторного создания традиционную испаряющую семантику в целевых объектах ARM, компилятор должен ввести или барьеры памяти вокруг каждого или записи переменной volatile для принудительного выполнения строгой порядок, который может отрицательно сказывается на производительности.

В архитектурах x86 и x64, по умолчанию используется значение /volatile:ms, потому что большая часть программного обеспечения, которое уже было создано для этих архитектур с помощью компилятора C Microsoft C-++ основывается на них.При компилировать x86 и x64 программы, можно указать параметр /volatile:iso, чтобы избежать ненужного доверия на традиционной испаряющей семантике и повысить уровень ошибки.

См. также

Другие ресурсы

Настройка программ для процессоров ARM (Visual C++)