1

I'm getting the following error when attempting to build on CentOS 6.4: The only flags being passed here are -Wall and -std=c++11, using gcc 4.7.2

/usr/local/include/rapidjson/writer.h: In member function ‘void rapidjson::Writer::WriteDouble(double)’: /usr/local/include/rapidjson/writer.h:173:53: error: there are no arguments to ‘_snprintf’ that depend on a template parameter, so a declaration of ‘_snprintf’ must be available [-fpermissive] /usr/local/include/rapidjson/writer.h:173:53: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)

The code in question: (from rapidjson/writer.h)

        void WriteDouble(double d) {
            char buffer[100];
#if _MSC_VER
            int ret = sprintf_s(buffer, sizeof(buffer), "%g", d);
#else
            int ret = snprintf(buffer, sizeof(buffer), "%g", d); //this line is the troublemaker
#endif
            RAPIDJSON_ASSERT(ret >= 1);
            for (int i = 0; i < ret; i++)
                    stream_.Put(buffer[i]);
    }

The top of the writer.h file looks like this:

#ifndef RAPIDJSON_WRITER_H_
#define RAPIDJSON_WRITER_H_

#include "rapidjson.h"
#include "internal/stack.h"
#include "internal/strfunc.h"
#include <cstdio>       // snprintf() or _sprintf_s()
#include <new>          // placement ne

Which led me to this question: cstdio stdio.h namespace.

As I understand the answer to the question above, the inclusion of cstdio should declare the snprintf symbol in the standard namespace. So, I thought to include stdio.h to get the symbol defined in the global namespace. The same compilation error results, regardless if I include cstdio, stdio.h, or both files (which I shouldn't have to do)

My question is two parts: Why is gcc looking for _snprintf and not snprintf? Or am I on the wrong track and is this related to the two-part name lookup that gcc does for template parameter binding? (ala 10.8.2, http://idlebox.net/2009/apidocs/gcc-4.4.1.zip/gcc-4.4.1/gcc_10.html#SEC315)

Community
  • 1
  • 1
jdt141
  • 4,993
  • 6
  • 35
  • 36

2 Answers2

0

Are you using the -ansi compile flag?

Using -ansi generally says that you want the headers to expose ONLY the interfaces mentioned in the C89 standard. But C89 did not describe snprintf

Jay
  • 13,803
  • 4
  • 42
  • 69
0

(Cannot comment yet, so I'm writing this as an answer).

Regarding your second question: It's unlikely this has to do with two-phase name lookup. The error message simply says there's an non-dependent undefined smybol (_snprintf).

Ok, why is that happening? The error message is about _snprintf, not the actually used snprintf in writer.h, so if I had to guess I'd say there's some other code redefining that name via #define snprintf _snprintf before including the STL headers. Is there something like that in your code? If possible, remove it.

Some other things to try: Move the inclusion of writer.h to the top of the file (i.e. before redefinition of snprintf occurs), if possible. If not possible, try to #undef snprintf before including writer.h.

Also, such a redefinition alone leads to a different error on my machine. To clarify this: How is the preprocessor symbol _GLIBCXX_USE_C99 defined on your system?

If this doesn't help, some more information is needed. Could you then post the complete error message (and perhaps a minimal example to reproduce)?

C-B
  • 56
  • 4