Skip to content

Commit

Permalink
compat: fall back on __va_copy if available
Browse files Browse the repository at this point in the history
Since an obvious implementation of va_list is to make it a pointer
into the stack frame, implementing va_copy as "dst = src" will work on
many systems.  Platforms that use something different (e.g., a size-1
array of structs, to be assigned with *(dst) = *(src)) will need some
other compatibility macro, though.

Luckily, as the glibc manual hints, such systems tend to provide the
__va_copy macro (introduced in GCC in March, 1997).  By using that if
it is available, we can cover our bases pretty well.

Discovered by building with CC="gcc -std=c89" on an amd64 machine:

 $ make CC=c89 strbuf.o
 [...]
 strbuf.c: In function 'strbuf_vaddf':
 strbuf.c:211:2: error: incompatible types when assigning to type 'va_list'
  from type 'struct __va_list_tag *'
 make: *** [strbuf.o] Error 1

Explained-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jonathan Nieder authored and Junio C Hamano committed Mar 8, 2011
1 parent ebeb609 commit 26db0f2
Showing 1 changed file with 10 additions and 1 deletion.
11 changes: 10 additions & 1 deletion git-compat-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,16 @@ void git_qsort(void *base, size_t nmemb, size_t size,
#endif

#ifndef va_copy
#define va_copy(dst,src) (dst) = (src)
/*
* Since an obvious implementation of va_list would be to make it a
* pointer into the stack frame, a simple assignment will work on
* many systems. But let's try to be more portable.
*/
#ifdef __va_copy
#define va_copy(dst, src) __va_copy(dst, src)
#else
#define va_copy(dst, src) ((dst) = (src))
#endif
#endif

/*
Expand Down

0 comments on commit 26db0f2

Please sign in to comment.