Note that there are some explanatory texts on larger screens.

plurals
  1. POMatching va_list types between compilers
    primarykey
    data
    text
    <p>I have a project that consists of a bunch of dynamically loaded modules. Originally, everything was always built with MSVC 2003, but lately I've been working on getting it to work with GCC. Everything has been going pretty smoothly, except for one problem. For 64-bit code, GCC and MSVC don't agree about what a <code>va_list</code> is. For 32-bit, things seem to line up fine. The problem the 64-bit mismatch causes is when a module built with one compiler has a public function with a <code>va_list</code> parameter and that function is called from a module built by the other compiler.</p> <p>The spec says nothing about what a <code>va_list</code> is, outside of <strong>Section 7.15 Variable arguments <code>&lt;stdarg.h&gt;</code></strong>, paragraph 3:</p> <blockquote> <p>The type declared is</p> <p><strong><code>va_list</code></strong></p> <p>which is an object type suitable for holding information needed by the macros <strong><code>va_start</code></strong>, <strong><code>va_arg</code></strong>, <strong><code>va_end</code></strong>, and <strong><code>va_copy</code></strong>.</p> </blockquote> <p>That paragraph just means this is all compiler dependent stuff - so, is there a way to make these two compilers agree on the contents of a 64-bit <code>va_list</code>? For least impact to my system, making GCC match the MSVC <code>va_list</code> would be best, but I'll take any solution I can get.</p> <p>Thanks for helping out!</p> <p>Edit:</p> <p>I did some 32-bit testing, and I have problems there too, which surprised me since there are supposedly no ABI differences between any 32-bit Intel platforms. The MSVC codebase I'm using defines all of the variadic function macros as:</p> <pre><code>typedef char *va_list; #define intsizeof(n) ((sizeof(n) + sizeof(int) - 1) &amp;~(sizeof(int) - 1)) #define va_start(ap, v) (ap = (va_list)&amp;(v) + intsizeof(v)) #define va_arg(ap, t) (*(t *) ((ap += intsizeof(t)) - intsizeof(t))) #define va_end(ap) (ap = (va_list)0) </code></pre> <p>I've simplified a bit from the real project, but this is the code I was using for my test. With GCC, this code definitely isn't correctly getting my arguments. Maybe it is just a bug, as Zack suggests below?</p> <p>Edit again:</p> <p>I get working results for the following 32-bit test application with <code>-O0</code>, <code>-O0</code>, and <code>-O2</code>, but not <code>-O3</code>, <code>-Os</code>, and <code>-Oz</code>:</p> <pre><code>typedef char *va_list; #define intsizeof(n) ((sizeof(n) + sizeof(int) - 1) &amp;~(sizeof(int) - 1)) #define va_start(ap, v) (ap = (va_list)&amp;(v) + intsizeof(v)) #define va_arg(ap, t) (*(t *) ((ap += intsizeof(t)) - intsizeof(t))) #define va_end(ap) (ap = (va_list)0) int printf(const char *format, ...); int f(int n, ...) { int r = 0; va_list ap; va_start(ap, n); while (n--) r = va_arg(ap, int); va_end(ap); return r; } int main(int argc, char **argv) { int r; r = f(1, 1, 2, 3, 4, 5); printf("%x\n", r); r = f(2, 1, 2, 3, 4, 5); printf("%x\n", r); r = f(3, 1, 2, 3, 4, 5); printf("%x\n", r); r = f(4, 1, 2, 3, 4, 5); printf("%x\n", r); r = f(5, 1, 2, 3, 4, 5); printf("%x\n", r); return 0; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload