Eli Zaretskii
2017-05-09 16:16:24 UTC
As followup to the previous problem I reported when building GDB 8.0
pretest, I upgraded to mingwrt-5.0, which fixed the issue with
to_string, but introduced a new problem -- linking GDB failed thusly:
d:/usr/lib/libmingwex.a(vsnprintf.o):(.text+0x0): multiple definition of `vsnprintf'
cli-script.o:d:/usr/include/stdio.h:427: first defined here
collect2.exe: error: ld returned 1 exit status
This happens because the GDB build defines __USE_MINGW_ANSI_STDIO in
its headers, and when a C++ program does that, including <stdio.h> and
<string> in a source file will (a) define vsnprintf as an inline
function, and (b) pull vsnprintf.o from libmingwex because it needs
__mingw_vsnprintf. But vsnprintf.c from libmingwex also defines (a
non-inline version of) vsnprintf, and thus the above error.
(This doesn't happen in C programs because for C stdio.h defines
vsnprintf as a static inline function.)
I attach below a small nonsense program, which I concocted from bits
and pieces of GDB's cli-script.c; it can be used to reproduce this
problem. It builds OK with mingwrt-3.22.2, but not with mingwrt-5.0,
using the same libstdc++ headers from the MinGW GCC 5.3.0
distribution.
Any ideas for solutions are welcome. (I assume that undefining
__USE_MINGW_ANSI_STDIO before including stdio.h is not a good idea,
since it will cause a non-compliant vsnprintf from msvcrt to be used,
which will subtly break the program.)
Here's the test program:
// ts.c
//
// Compile with 'g++ -std=gnu++11 -O2 -c ts.c -o ts.o',
// then examine the result with 'nm -A'.
// Or try building with 'g++ -std=gnu++11 -O2 ts.c -o ts.exe',
// and see it fail.
#define __USE_MINGW_ANSI_STDIO 1
#include <stdio.h>
// The following 3 macros are for mingwrt-3.22, not needed for 5.0
#ifndef _GLIBCXX_USE_C99
#define _GLIBCXX_USE_C99 1
#endif
#ifndef _ISOC99_SOURCE
#define _ISOC99_SOURCE
#endif
#ifndef _GLIBCXX_HAVE_WCSTOF
#define _GLIBCXX_HAVE_WCSTOF 1
#endif
#include <string>
#include <vector>
struct string_view
{
string_view (const char *str_, size_t len_)
: str (str_), len (len_)
{}
const char *str;
size_t len;
};
class user_args
{
public:
/* Save the command line and store the locations of arguments passed
to the user defined function. */
explicit user_args (const char *line);
/* Insert the stored user defined arguments into the $arg arguments
found in LINE. */
std::string insert_args (const char *line) const;
/* The arguments. Each element points inside M_COMMAND_LINE. */
std::vector<string_view> m_args;
};
static std::vector<user_args> user_args_stack;
std::string
user_args::insert_args (const char *line) const
{
std::string new_line;
new_line += std::to_string (m_args.size ());
return new_line;
}
int
main (int argc, char *argv[])
{
char line[80];
const user_args &args = user_args_stack.back ();
args.insert_args (line);
return 0;
}
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
MinGW-users mailing list
MinGW-***@lists.sourceforge.net
This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same. Disregard for the list etiquette may cause your account to be moderated.
_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Also: mailto:mingw-users-***@lists.sourceforge.net?subject=unsubscribe
pretest, I upgraded to mingwrt-5.0, which fixed the issue with
to_string, but introduced a new problem -- linking GDB failed thusly:
d:/usr/lib/libmingwex.a(vsnprintf.o):(.text+0x0): multiple definition of `vsnprintf'
cli-script.o:d:/usr/include/stdio.h:427: first defined here
collect2.exe: error: ld returned 1 exit status
This happens because the GDB build defines __USE_MINGW_ANSI_STDIO in
its headers, and when a C++ program does that, including <stdio.h> and
<string> in a source file will (a) define vsnprintf as an inline
function, and (b) pull vsnprintf.o from libmingwex because it needs
__mingw_vsnprintf. But vsnprintf.c from libmingwex also defines (a
non-inline version of) vsnprintf, and thus the above error.
(This doesn't happen in C programs because for C stdio.h defines
vsnprintf as a static inline function.)
I attach below a small nonsense program, which I concocted from bits
and pieces of GDB's cli-script.c; it can be used to reproduce this
problem. It builds OK with mingwrt-3.22.2, but not with mingwrt-5.0,
using the same libstdc++ headers from the MinGW GCC 5.3.0
distribution.
Any ideas for solutions are welcome. (I assume that undefining
__USE_MINGW_ANSI_STDIO before including stdio.h is not a good idea,
since it will cause a non-compliant vsnprintf from msvcrt to be used,
which will subtly break the program.)
Here's the test program:
// ts.c
//
// Compile with 'g++ -std=gnu++11 -O2 -c ts.c -o ts.o',
// then examine the result with 'nm -A'.
// Or try building with 'g++ -std=gnu++11 -O2 ts.c -o ts.exe',
// and see it fail.
#define __USE_MINGW_ANSI_STDIO 1
#include <stdio.h>
// The following 3 macros are for mingwrt-3.22, not needed for 5.0
#ifndef _GLIBCXX_USE_C99
#define _GLIBCXX_USE_C99 1
#endif
#ifndef _ISOC99_SOURCE
#define _ISOC99_SOURCE
#endif
#ifndef _GLIBCXX_HAVE_WCSTOF
#define _GLIBCXX_HAVE_WCSTOF 1
#endif
#include <string>
#include <vector>
struct string_view
{
string_view (const char *str_, size_t len_)
: str (str_), len (len_)
{}
const char *str;
size_t len;
};
class user_args
{
public:
/* Save the command line and store the locations of arguments passed
to the user defined function. */
explicit user_args (const char *line);
/* Insert the stored user defined arguments into the $arg arguments
found in LINE. */
std::string insert_args (const char *line) const;
/* The arguments. Each element points inside M_COMMAND_LINE. */
std::vector<string_view> m_args;
};
static std::vector<user_args> user_args_stack;
std::string
user_args::insert_args (const char *line) const
{
std::string new_line;
new_line += std::to_string (m_args.size ());
return new_line;
}
int
main (int argc, char *argv[])
{
char line[80];
const user_args &args = user_args_stack.back ();
args.insert_args (line);
return 0;
}
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
MinGW-users mailing list
MinGW-***@lists.sourceforge.net
This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same. Disregard for the list etiquette may cause your account to be moderated.
_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Also: mailto:mingw-users-***@lists.sourceforge.net?subject=unsubscribe