Итог:
Нет, это определенно небезопасно .Это будет работать во многих типичных ситуациях, но va_args - это не то же самое, что передача аргументов непосредственно в функцию.
Пожалуйста, пожалуйста, пожалуйста, используйте NSInvocation
. Это решаетоколо 99% этого для вас, при этом будучи намного безопаснее.Могут быть крайние случаи, которые он не решает (например, векторы SSE / AVX в списках параметров), но это будет на шаг впереди того, что вы могли бы взломать вместе.
Давайте разберем этопо архитектуре, и посмотрите, где это может , вероятно, работать.
Универсальный
Эти проблемы будут появляться везде, без реальных решений.
Плавающие точки всегда увеличиваются в два раза, когда передаются как va_args.См. стандарт C , раздел §6.5.2.2
То же самое верно для short
с и char
с.Все они тоже будут увеличены, что вызовет много боли и страданий при прохождении.Технически (в отличие от чисел с плавающей точкой, поскольку они иногда передаются в специальных регистрах FPU), для целочисленных типов вы можете решить эту проблему, заключив их в единую элементную структуру.Это предотвратит их продвижение.Пожалуйста, не делайте этого.
Союзы или сложные структуры.Требуется дополнительное выравнивание и дополнения и соображения.Вам нужно будет углубиться в код компилятора, если вы хотите стабильное решение для этого.
Ситуация ДАЖЕ сложнее, если вы начинаете касаться возвращаемых значений, и вам необходимо понимать, когда структуры упаковываются в регистры для возвращаемых значений по архитектуре (см. a лот из предыдущих обсуждений).
PowerPC
Мне это не мешает.Если вам все еще нужно настроить таргетинг на эти устройства MacOS, две вещи:
Я чувствую себя ОЧЕНЬ плохо для вас.
У вас, вероятно, больше контекстачем я делаю на этом.Удачи, и боже мой.
x86
32-bit x86 довольно вменяемый.Там нет сложной передачи аргументов регистра, вне моей головы, и я чувствую, что это, вероятно, довольно вменяемым.Самым важным, помимо упомянутых ранее проблем, будут проблемы, вызванные процессором x87.Избегайте поплавков, и вы, вероятно, не будете сжигать мир здесь.
x86-64
64-bit x86 - это еще один зверь в целом.Вам нужно много узнать о том, как компилятор назначает регистры аргументам (и возвращаемым значениям!) И, конечно, новые регистры SSE для плавающих точек.
ARMv6 / ARMv7 / ARMv7s (32-битныйARM)
Я собираюсь объединить их, с этой точки зрения нет существенных различий.
Как и x86-64, вам придется немного узнать о том, какие регистры идут кудастек, если вы хотите быть на 100% безопасным, но прохождение с плавающей запятой здесь проще, если память вспоминает.
Apple Руководство по ABI здесь будет вашим другом.
ARM64
Здесь мои знания самые ненадежные, и я прошу прощения, если какая-либо из этих данных неверна.
Большинство вызовов функций выполняются полностью через регистры, поэтому все наши предыдущие проблемы все еще остаютсяВот.Теперь есть новые регистры FPU, с которыми вам придется иметь дело для ваших плавающих точек, но ничего непреодолимого, если вы дошли до этой точки.