1

I am currently getting a build error. this error looks like this

C:/mingw64/x86_64-w64-mingw32/include/c++/x86_64-w64-mingw32/bits/c++locale.h: In function 'int std::__convert_from_v(int* const&, char*, int, const char*, ...)':
C:/mingw64/x86_64-w64-mingw32/include/c++/x86_64-w64-mingw32/bits/c++locale.h:74:48: error: expected primary-expression before ',' token
     const int __ret = __builtin_vsnprintf(__out, __size, __fmt, __args);

Upon investigation I noticed the code in C++Locale.h looks like this

// Written by Benjamin Kosnik <bkoz@redhat.com>

#ifndef _GLIBCXX_CXX_LOCALE_H
#define _GLIBCXX_CXX_LOCALE_H 1

#pragma GCC system_header

#include <clocale>

#define _GLIBCXX_NUM_CATEGORIES 0

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  typedef int*          __c_locale;

  // Convert numeric value of type double and long double to string and
  // return length of string.  If vsnprintf is available use it, otherwise
  // fall back to the unsafe vsprintf which, in general, can be dangerous
  // and should be avoided.
  inline int
  __convert_from_v(const __c_locale&, char* __out,
           const int __size __attribute__((__unused__)),
           const char* __fmt, ...)
  {
    char* __old = std::setlocale(LC_NUMERIC, 0);
    char* __sav = 0;
    if (__builtin_strcmp(__old, "C"))
      {
    const size_t __len = __builtin_strlen(__old) + 1;
    __sav = new char[__len];
    __builtin_memcpy(__sav, __old, __len);
    std::setlocale(LC_NUMERIC, "C");
      }

    __builtin_va_list __args;
    __builtin_va_start(__args, __fmt);


#ifdef _GLIBCXX_USE_C99
    const int __ret = __builtin_vsnprintf(__out, __size, __fmt, __args);
#else
    const int __ret = __builtin_vsprintf(__out, __fmt, __args);
#endif

    __builtin_va_end(__args);

    if (__sav)
      {
    std::setlocale(LC_NUMERIC, __sav);
    delete [] __sav;
      }
    return __ret;
  }

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif

Now this error goes away If i change the parameter in the line

  inline int
  __convert_from_v(const __c_locale&, char* __out,
           const int __size __attribute__((__unused__)),
           const char* __fmt, ...)

from __out to something else like __aout or if I remove the inline keyword. I know i should not be making changes in the default imp. files . This file is in the folder

C:\mingw64\x86_64-w64-mingw32\include\c++\x86_64-w64-mingw32\bits

Any suggestions on what I could do to resolve this issue without making changes to the actual files of Mingw GCC 64 bit?

James Franco
  • 4,516
  • 10
  • 38
  • 80

1 Answers1

6

It looks like you have a header file of your own that is defining __out. Just find where it is, and use a different name. Note that identifiers starting with double underscore are reserved in C++; this is why the parameter names in c++locale.h start with __, so they don't clash with anything the user might define. So you shouldn't be using __out for your own purposes (if indeed that is where the problem lies).

Having said that, nothing bad will happen to you if you edit c++locale.h to change all instances of __out to __aout.

Updated to add: I think Ross Ridge and I have cracked it between us in the comments. This is from the mingw header file i686-w64-mingw32\include\driverspecs.h:

/*
 * FIXME: These annotations are not driver-only and does not belong here
 */
#define __in
#define __in_bcount(Size)
#define __in_ecount(Size)

#define __out
#define __out_bcount(Size)
#define __out_bcount_part(Size, Length)
#define __out_ecount(Size)

So the definition of __out makes this header file incompatible with c++locale.h -- a mingw bug.

TonyK
  • 16,761
  • 4
  • 37
  • 72
  • 1
    It might actually be an issue with the MinGW headers trying to be compatible with Microsoft Visual C++ as their headers define `__out`. – Ross Ridge Mar 10 '15 at 00:54
  • 1
    I don't have this MinGW-w64 headers to check, but there's a possibility somewhere in one of them there's a `#define __out` line for compatibility with Microsoft Visual C++. The later headers define `__out` as an annotation for function declarations so the compiler can warn about certain programming errors. It's effectively part of a poorly documented and now obsolete external interface, one notably used by older versions of the Windows SDK. See http://stackoverflow.com/questions/9834550/meaning-of-in-out-in-opt – Ross Ridge Mar 10 '15 at 17:16
  • @RossRidge: That's interesting! But in this case, the unambiguous intention is to use `__out` as a variable name. So perhaps those obsolete MS VC++ headers are being included too, which spoils things for `c++locale.h`. – TonyK Mar 10 '15 at 17:35
  • 2
    I doubt that the Visual C++ headers are being included. I'm suggesting the one of the headers that was written by the MinGW-w64 team contain the exact line `#define __out`, which would allow code that used the VC++ `__out` macro to compile without errors, but not provide the actual functionality. The error message that OP received is consistent with `__out` being defined with no contents. The fact that this would cause `c++locale.h`, a header file included with MinGW-w64 but not written by them, to miscompile would mean that I'm suggesting there's a bug in MinGW-w64. – Ross Ridge Mar 10 '15 at 18:02
  • @RossRidge: Ha! I found it! You are absolutely right -- see my latest update. – TonyK Mar 10 '15 at 18:06