Это не портативный, извините.Формат va_list зависит от компилятора / платформы.
Вы должны использовать va_arg () для доступа к va_list, и вы должны передать правильный тип аргумента в va_list.
Однако я считаю,возможно, что если вы передадите тип правильного размера в va_arg, это сработает.то есть.тип обычно не актуален, только его размер.Тем не менее, даже это не гарантирует работу во всех системах.
Я думаю, что я бы посоветовал взглянуть на ваш дизайн и посмотреть, если вы можете найти альтернативный дизайн - есть ли более подробная информация о том, почему вы пытаетесь сделатьэто что вы можете поделиться?Можете ли вы вместо этого передать va_list обратным вызовам?
Обновление
Причина, по которой побайтовый подход не работает, вероятно, довольно сложна.Что касается стандарта C, причина, по которой он не работает, заключается в том, что он недопустим - вы можете использовать va_arg только для доступа к идентичным типам, которые были переданы в функцию.
Но я подозреваю, что выхотелось бы знать, что происходит за кулисами:)
Первая причина заключается в том, что когда вы читаете, передаете функцию "char" в функцию, она фактически автоматически преобразуется в int, поэтому сохраняется в va_arg каквнутр.Поэтому, когда вы читаете символ, вы читаете память типа int, а не символ, то есть вы фактически не читаете байт за раз.
Еще одна причина состоит в том, чточтобы сделать выравнивание - на некоторых архитектурах (одним примером были бы совсем недавние процессоры ARM), «двойник» должен быть выровнен по 64-битной (или иногда даже 128-битной) границе.То есть для значения указателя p p% 16 (модуль p 16, в байтах, т. Е. 128 бит) должен равняться 0. Таким образом, когда они упакованы в va_arg, компилятор, вероятно, будет гарантировать, что любые двойные значения имеют пространство(заполнение) добавлено, чтобы они возникали только при правильном выравнивании - но вы не учитываете это, когда читаете записи байт за раз.
(Могут быть и другие причины - яне очень хорошо знаком с внутренними работами va_arg.)