Возвращает va_list в C?
Я хотел бы написать функцию с возвращаемым типом va_list.
пример: va_list MyFunc(va_list args);
безопасен и переносится?
Ответы
Ответ 1
va_list
может (но не гарантируется) быть типом массива, поэтому вы не можете передать или вернуть его по значению. Код, который выглядит так, как будто это может быть просто передачей/возвратом указателя на первый элемент, поэтому вы можете использовать параметр в вызываемом, но вы можете воздействовать на оригинал.
Формально вы можете сказать, что va_list
- это тип объекта, а не тип значения. Вы копируете его с помощью va_copy
, а не с присвоением или с помощью параметров функции/возврата.
Ответ 2
В то время как вы можете определенно return
такое значение, я не уверен, что возвращаемое значение может быть полезно полезным.
Поскольку обработка va_list
требует специальной обработки (va_end()
, требуемой после va_start()
и va_copy()
), а макросам va_start/copy
и va_end
даже разрешено содержать { }
для обеспечения соблюдения этого спаривания, вы не можете позвонить один без другого.
Ответ 3
Независимо от того, что говорит языковой стандарт, это вряд ли будет работать на практике. A va_list
скорее всего будет указателем на запись вызова, помещенную в стеке вызывающим абонентом в интересах вызываемого абонента. Как только вызов возвращается, эта память в стеке является справедливой игрой для повторного использования.
Возврат типа va_list
вряд ли фактически скопирует содержимое списка обратно вызывающему. Хотя это была бы допустимая реализация C, если стандарт требует, чтобы это было сделано, это было бы дефектом в спецификации.
Ответ 4
Передача указателя на другую функцию сильно отличается от возвращая этот указатель. Многие/большинство реализаций хранят фактические переменные аргументы в кадре стека, которые уничтожаются, когда Функция vararg возвращает. (т.е. возвращая va_list или указатель на один, оставит вас с указателями на локальные переменные, которые разрушен). - nos
ну в моем случае я бы возвращал va_list, но спасибо за предупреждение - Айри Угур Колтук
Если вы передадите указатель на va_list
в функцию MyFunc(va_list *args)
, вам не нужно передавать измененный список (через va_arg(*args, type)
) назад, так как MyFunc
изменяет исходный список.