This is the mail archive of the cygwin mailing list for the Cygwin 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]

Re: va_list and char* are ambiguous


On Mon, Mar 3, 2014 at 1:47 PM, Kai Tietz wrote:
> Hi,
>
> cygwin64 shares for 64-bit the ABI of Windows native.  This is caused
> by different reasons (eg. unwind-table description for prologue, etc).
> So for Windows targets va_list is indeed of 'char *' type.  And this
> is ok.  The variant of x86_64 abi, which uses indeed a
> structure-variant for variadic-arguments plus some call-abi
> extensions, isn't recommented for on Windows.  If your linux code
> relies on structure-variadic x86_64-ABI, it seems to me broken, and
> needs to be ported.
>
> Hope this answers your question.
>
> Regards,
> Kai

I will take that as a negative answer to modifying the internal
definition of va_list...

In case anyone else googles this problem and finds this thread: my
main problem was to make string literals be matched against the
ellipsis overload, and not the va_list overload, when the two are
available. Apparently, gcc is too smart for its own good (perhaps
mandated by the standard) and will always automatically remove the
constness of a string literal and select the va_list overload (and
warn you about it!). I found three solutions, both of which require
modifications of affected code.

1) don't overload, rename one of the functions -- may affect much more
code than what is affected by the original problem.
2) cast your string literal to (void *) -- a bit confusing, and causes
a warning if __attribute__ ((format (printf, ...))) is used.
3) introduce a temporary const char *tmp = "string literal" and pass
that. gcc won't try to cast away the constness of a variable and will
match the ellipsis.

Code example:

#include <cstdarg>
#include <iostream>
using namespace std;
void foo (...)        { cout << "varargs\n"; }
void foo (va_list ap) { cout << "va_list\n"; }
int main () {
    foo ("");                       // va_list
    foo ((const char *)"");         // va_list
    foo ((const char *)NULL);       // varargs
    foo ((void *)"");               // varargs
    foo ((const char *)(void *)""); // va_list
    const char *bar = "";
    foo (bar);                      // varargs
}

-- Irfan

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]