This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
On 01/29/2018 05:08 PM, Alexey Neyman wrote:
> Okay, attached is a quick simulation - using a similar code that uses
> va_arg in the caller then either passes a copy of the va_list to a
> callee, or passes it by pointer.
Your simulation isn't testing the same thing as what newlib is doing.
Of course you're going to see garbage.
>
> #include <stdio.h>
> #include <stdarg.h>
>
>
> static void f1(int i,
> #if defined(USE_VA_POINTERS)
> va_list *p_ap
This is what newlib is using. We are taking a va_list * parameter for
the helper function.
> #else
> va_list ap
This is irrelevant. That's not what newlib is doing, so we don't care
how it fails to modify the callee.
> static void f2(va_list ap)
> {
> int i, x;
> #if !defined(USE_VA_POINTERS)
> va_list ap2;
>
> va_copy(ap2, ap);
This doesn't match what newlib is doing. We need to perform the va_copy
unconditionally, because we need to take our 'va_list ap' and convert it
into something we can take the address of to pass it to a 'va_list *ap'
f1() function.
> #endif
> for (i = 0; i < 10; i++) {
> x = va_arg(ap, int);
No, that's not what newlib is doing, either. You do NOT want to be
mixing ap and ap2 in the same function.
> printf("%s#%u: %u\n", __func__, i, x);
> #if defined(USE_VA_POINTERS)
> #if defined(__x86_64__)
> f1(i, (va_list *)ap);
EWWWW. Gross. NOT at all what newlib is doing. If USE_VA_POINTERS,
you want platform-independent code that calls
f1(i, &ap2);
and then use ap2 (and ONLY ap2) within the body of f2.
Here's your program, corrected to what newlib should be doing:
#include <stdio.h>
#include <stdarg.h>
static void f1(int i, va_list *p_ap)
{
double x;
x = va_arg(*p_ap, double);
printf("%s#%u: %f\n", __func__, i, x);
}
static void f2(va_list ap)
{
int i, x;
va_list ap2;
va_copy(ap2, ap);
for (i = 0; i < 10; i++) {
x = va_arg(ap2, int);
printf("%s#%u: %u\n", __func__, i, x);
f1(i, &ap2);
}
}
void fx(int dummy, ...)
{
va_list ap;
va_start(ap, dummy);
f2(ap);
va_end(ap);
}
int main(void)
{
fx(0, 1, 0.1, 2, 0.2, 3, 0.3, 4, 0.4, 5, 0.5, 6, 0.6,
7, 0.7, 8, 0.8, 9, 0.9, 10, 0.1);
return 0;
}
which shows NO corruption.
$ ./foo
f2#0: 1
f1#0: 0.100000
f2#1: 2
f1#1: 0.200000
f2#2: 3
f1#2: 0.300000
f2#3: 4
f1#3: 0.400000
f2#4: 5
f1#4: 0.500000
f2#5: 6
f1#5: 0.600000
f2#6: 7
f1#6: 0.700000
f2#7: 8
f1#7: 0.800000
f2#8: 9
f1#8: 0.900000
f2#9: 10
f1#9: 0.100000
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
Attachment:
signature.asc
Description: OpenPGP digital signature
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |