public inbox for libc-help@sourceware.org
 help / color / mirror / Atom feed
* appending last argument to (wrap(ed)) variadic function call
@ 2020-02-24  3:09 Alexandre François Garreau
  2020-02-24 11:20 ` Florian Weimer
  0 siblings, 1 reply; 5+ messages in thread
From: Alexandre François Garreau @ 2020-02-24  3:09 UTC (permalink / raw)
  To: libc-help

I want to wrap a call to a variadic function (which have both a really 
variadic version, and one taking a va_list as argument), and let its last 
argument be fixed by this wrapper (accordingly modifying the fixed argument 
that specify about the variable arguments and their types)… how can I do 
that?

That last argument happens to need to be declared (in a local scope, in my 
case), so I can do it with a macro, unless I resort to GNU compound 
statements (“({char * trailing[2]; ...; ret_value;})”).

I want to do something like:
#define escanf(argc, format, ...) ({ char trailing[2], *format = 
astrcat(format, "%1s"); int ret = escanf(format, __VA_ARGS__, &trailing); 
free(format); ret != argc; })

But in a function… possibly itself variadic, so working with a va_list.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: appending last argument to (wrap(ed)) variadic function call
  2020-02-24  3:09 appending last argument to (wrap(ed)) variadic function call Alexandre François Garreau
@ 2020-02-24 11:20 ` Florian Weimer
  2020-02-24 12:39   ` Alexandre François Garreau
  0 siblings, 1 reply; 5+ messages in thread
From: Florian Weimer @ 2020-02-24 11:20 UTC (permalink / raw)
  To: Alexandre François Garreau; +Cc: libc-help

* Alexandre François Garreau:

> I want to wrap a call to a variadic function (which have both a really 
> variadic version, and one taking a va_list as argument), and let its last 
> argument be fixed by this wrapper (accordingly modifying the fixed argument 
> that specify about the variable arguments and their types)… how can I do 
> that?

You cannot access the last argument unless you know the types of all the
preceding arguments.  A GCC extension, __builtin_va_arg_pack_len, allows
you to get the number of arguments, but if they have unknown types, that
does not really help to solve this problem.

However, you can implement something like this in a fairly
straightforward way in C++11.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: appending last argument to (wrap(ed)) variadic function call
  2020-02-24 11:20 ` Florian Weimer
@ 2020-02-24 12:39   ` Alexandre François Garreau
  2020-02-24 12:49     ` Florian Weimer
  0 siblings, 1 reply; 5+ messages in thread
From: Alexandre François Garreau @ 2020-02-24 12:39 UTC (permalink / raw)
  To: Florian Weimer; +Cc: libc-help

Le lundi 24 février 2020, 12:20:22 CET Florian Weimer a écrit :
> * Alexandre François Garreau:
> > I want to wrap a call to a variadic function (which have both a really
> > variadic version, and one taking a va_list as argument), and let its
> > last argument be fixed by this wrapper (accordingly modifying the
> > fixed argument that specify about the variable arguments and their
> > types)… how can I do that?
> 
> You cannot access the last argument unless you know the types of all the
> preceding arguments.  A GCC extension, __builtin_va_arg_pack_len,
> allows you to get the number of arguments, but if they have unknown
> types, that does not really help to solve this problem.

But I don’t want to access it but to fix/set it… 

Also I have access to the format string, so theorically I could know all 
the types and the number of arguments… but anyway I’d end with a va_arg at 
some point, and no other way to pass a variable number of argument… so no 
way to “concat” two sequences of args… va_list stays pretty opaque to me 
(and as it is unspecified, I wouldn’t expect it to be portable anyway…).

> However, you can implement something like this in a fairly
> straightforward way in C++11.

I’d like to stay in plain C… I know C++ can already do all sort of things…

Are there a lot of bare C features which are implemented internally with 
C++ inside glibc?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: appending last argument to (wrap(ed)) variadic function call
  2020-02-24 12:39   ` Alexandre François Garreau
@ 2020-02-24 12:49     ` Florian Weimer
  2020-02-25  4:33       ` Alexandre François Garreau
  0 siblings, 1 reply; 5+ messages in thread
From: Florian Weimer @ 2020-02-24 12:49 UTC (permalink / raw)
  To: Alexandre François Garreau; +Cc: libc-help

* Alexandre François Garreau:

> Le lundi 24 février 2020, 12:20:22 CET Florian Weimer a écrit :
>> * Alexandre François Garreau:
>> > I want to wrap a call to a variadic function (which have both a really
>> > variadic version, and one taking a va_list as argument), and let its
>> > last argument be fixed by this wrapper (accordingly modifying the
>> > fixed argument that specify about the variable arguments and their
>> > types)… how can I do that?
>> 
>> You cannot access the last argument unless you know the types of all the
>> preceding arguments.  A GCC extension, __builtin_va_arg_pack_len,
>> allows you to get the number of arguments, but if they have unknown
>> types, that does not really help to solve this problem.
>
> But I don’t want to access it but to fix/set it…

Sorry, I don't understand.  Replacing or even adding an argument
requires knowledge of the location of the argument.

> Also I have access to the format string, so theorically I could know all 
> the types and the number of arguments… but anyway I’d end with a va_arg at 
> some point, and no other way to pass a variable number of argument… so no 
> way to “concat” two sequences of args… va_list stays pretty opaque to me 
> (and as it is unspecified, I wouldn’t expect it to be portable anyway…).

va_list simply does not have this kind of type information.  It's
basically a forward iterator, and in order to advance it, you need to
supply the correct type via va_arg.  It's also not possible to construct
a va_list from scratch, you can only get a tail of an argument list that
was already present in the program.  (There are libraries such as libffi
which get around this.)

The easiest way to achieve what you want is to supply a fix hint to the
actual implementation, which then applies the change at the right point
during the va_list iteration.

> Are there a lot of bare C features which are implemented internally with 
> C++ inside glibc?

There are none today.  On the technical side, bootstrapping a
cross-toolchain (binutils, GCC, glibc) is a concern, along with compile
time increases when building glibc.  And of course there are many
non-technical concerns.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: appending last argument to (wrap(ed)) variadic function call
  2020-02-24 12:49     ` Florian Weimer
@ 2020-02-25  4:33       ` Alexandre François Garreau
  0 siblings, 0 replies; 5+ messages in thread
From: Alexandre François Garreau @ 2020-02-25  4:33 UTC (permalink / raw)
  To: libc-help; +Cc: Florian Weimer

Le lundi 24 février 2020, 13:49:51 CET Florian Weimer a écrit :
> The easiest way to achieve what you want is to supply a fix hint to the
> actual implementation, which then applies the change at the right point
> during the va_list iteration.

Yes but I am to call vasprintf or vsscanf… so I will need to pass a 
va_list anyway, and it will not be me who will call va_arg… and I don’t 
know the parameters number in advance…

Does that mean that I should either fix the number of parameters (so 
abandon variadicity) or reimplement vsscanf myself?

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-02-25  4:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-24  3:09 appending last argument to (wrap(ed)) variadic function call Alexandre François Garreau
2020-02-24 11:20 ` Florian Weimer
2020-02-24 12:39   ` Alexandre François Garreau
2020-02-24 12:49     ` Florian Weimer
2020-02-25  4:33       ` Alexandre François Garreau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).