2013-12-16 3 views
4

У меня есть с-функцию, которая использует varadic аргументы стандартным способом, ниже упрощенный пример:stdargs [va_start(), va_arg() и т. Д.] Сломан на arm64?

void func(parameter,...) { 
    va_list args; 
    va_start(args, parameter); 

    //process args 
    v1 = va_arg(args,sometype); 
    v2 = va_arg(args,sometype); 
     ... 
    vn = va_arg(args,sometype); 

    va_end(args); 
} 


//call func 

func(parameter, p1, p2, ..., pn); 

на всех устройствах armv7s и нижней, а также всех тренажеров в том числе 64-битной тренажере это преуспевает и переменной v1 для vn назначается p1 в pn, но когда это выполняется на arm64, кажется, что вариационный список обратный (v1 = pn, v2 = pn-1, ..., vn = p1)

Есть ли какое-либо исправление для это? Или я пропустил документацию, описывающую это изменение?

Благодаря

EDIT:

я не упомянул ключевой элемент к этому вопросу, что я не думаю, чтобы упомянуть прежде. Я пытался пересказывать невариантные функции с общей вариационной функцией.

Примечание: используемый компилятор был Apple, LLVM 5,0

+5

Можете ли вы дать нам реальный пример выполнения? –

+0

быстрый и грязный обходной путь: отключите arm64 в настройках вашего проекта: -p приложение будет медленнее на iphone5, но пользователи iphone5s не заметят, потому что iphone5s по-прежнему является самым быстрым телефоном. (приложение по-прежнему будет быстрее на iphone5, чем на iphone5.) плюс: двоичный файл будет меньше, если вы опустите архитектуру. проблема с компилятором наверняка будет исправлена ​​когда-нибудь, и когда это произойдет, вы можете повторно использовать arm64. – Michael

+0

Проголосовало за утверждение ошибки компилятора без публикации кода. Это просто смешно. – gnasher729

ответ

1

Во-первых, я хочу извиниться за не отвечает в течение разумного периода времени. Это было в прошлом месяце.

Я разместил этот вопрос на форуме Apple, и кажется, что способ, которым параметры упакованы в вариационные функции, отличается от того, как параметры пакета невариантных функций.

Таким образом, хотя это работает в armv7 и armv7s, вы не можете зависеть от него, чтобы работать в arm64 или даже при применении высокого уровня оптимизации.

Я чувствую, что, если это так, то это нарушает ABI, но я возьму его за то, что он есть.

+0

Рад, что ты узнал, что ты не сумасшедший. Я согласен, что это нарушает стандартное поведение. Похоже, вам придется ждать исправления из яблока. – ldrumm

+0

@Bryce Вы можете показать ссылку на свой вопрос на форуме Apple? – Ossir

+0

@Ossir https://devforums.apple.com/message/927626#927626 –

2

Я подозреваю, что это связано с изменением в том, как аргументы передаются функции.

Есть три способа сделать это: в регистрах, в стеке и комбинация обоих, которая зависит от числа и типа аргументов. Кажется, что существует различие между архитектурами ARMv6, ARMv7 и ARM64 в отношении того, к какому соглашению придерживается ABI.

Независимо от фактического соглашения, компилятор должен обрабатывать это прозрачно, поэтому вам, возможно, придется изучить обновление инструментальной цепочки, если оно не ведет себя по стандарту (вы не упомянули компилятор в своем вопросе, но это ключ).

Apple's documentation в различных соглашениях о вызовах в разных версиях архитектуры может быть полезным здесь для отслеживания любых изменений, не учтенных вашим компилятором.

Для получения дополнительной информации о том, как ARM ожидает, что аргументы должны быть переданы, смотрите раздел 5.5 Procedure Call Standard for the ARM architecture(ARMv6, ARMv7 и section 5.4 in the 64 bit version of the ABI

0

Varargs работают только в том случае, если вы используете одни и те же типы в вызывающем и вызываемом абонентах. Если, например, вы передаете 1 и попытаетесь прочитать его как NSInteger, это не сработает на 64 бит, потому что программист не понял varargs, а не из-за ошибки компилятора.

Мы по-прежнему не видели никакого кода, который терпит неудачу.

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