undefined reference to __C11 (std::va_list)

The use of variable argument lists is causing an undefined reference in my C++ code. How can I fix this?

I have two source files that use va_args. But each one names std::va_list differently. Passing the output of nm through c++filt, I see this in one of the files:

00000000000022a0 T lib::sappendv(char **, int, char const *, __C1 *)

In the other, I see this:

0000000000002ea0 T lib::Clogger::printv( (int, char const *, __C11 *))
                 U lib::sappendv(char **, int, char const *, __C11 *)

Why does one source file use __C11, and the other __C1?

bgreen-


__C1 and __C11 look like compiler generated types.

  1. Use pgdecode instead of c++filt to get an accurate C++ demangling: nm t.o | pgdecode

  2. Make sure that you always #include stdarg.h , and not varargs.h. varargs is not
    ansi standard, and could cause trouble.

If this does not solve your problem, send us a small example that reproduces the problem so
that we may look into it.

Here is sample code that demonstrates the problem.

Try to compile these two files into an executable. Note the comment in bug.cxx.

Here is what I get:

$ pgCC bug.cxx bug1.cxx
bug.o: In function `sprint(char const *,...)':
bug.cxx:(.text+0x92): undefined reference to `sprintv(char const *, __C11 *)'

bug.cxx:

#include <string>  // comment this line out for a successful build
#include <cstdarg>

char *sprintv(const char *fmt,std::va_list args);

void sprint(const char *fmt,...)
{
    va_list args;
    va_start(args,fmt);
    sprintv(fmt,args);
    va_end(args);
}

int main()
{
    sprint("%d",1);
}

bug1.cxx:

#include <string>
#include <cstdarg>

char *sprintv(const char *fmt,std::va_list args)
{
    char *msgbuf = 0;
    return msgbuf;
}

bgreen-

Thank you.
This is a bug in our C++ compiler. I have filed TPR 3976 to track it.

In the mean time, you can change a line our header file /usr/pgi/linux86-64/include/va_list.h
to work around the bug:



*** va_list.h.bad Thu Oct 12 13:19:44 2006
— va_list.h Thu Oct 12 13:20:16 2006


*** 19,25 ****
extern “C” {
#endif /* __cplusplus */

! typedef struct {
unsigned int gp_offset;
unsigned int fp_offset;
char * overflow_arg_area; /* Address of memory args area. /
— 19,25 ----
extern “C” {
#endif /
__cplusplus */

! typedef struct __pgi_tag {
unsigned int gp_offset;
unsigned int fp_offset;
char * overflow_arg_area; /* Address of memory args area. */