1

尝试在 CentOS 6.4 上构建时出现以下错误:此处传递的唯一标志是 -Wall 和 -std=c++11,使用 gcc 4.7.2

/usr/local/include/rapidjson/writer.h:在成员函数'void rapidjson::Writer::WriteDouble(double)'中:/usr/local/include/rapidjson/writer.h:173:53:错误:有'_snprintf' 没有依赖于模板参数的参数,因此'_snprintf' 的声明必须可用 [-fpermissive] /usr/local/include/rapidjson/writer.h:173:53:注意:(如果你使用“-fpermissive”,G++ 将接受您的代码,但不允许使用未声明的名称)

有问题的代码:(来自 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]);
    }

writer.h 文件的顶部如下所示:

#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

这让我想到了这个问题:cstdio stdio.h namespace

据我了解上述问题的答案,包含 cstdio 应在标准命名空间中声明 snprintf 符号。所以,我想包括 stdio.h 来获取在全局命名空间中定义的符号。无论我是否包含 cstdio、stdio.h 或两个文件(我不应该这样做),都会产生相同的编译错误

我的问题是两个部分:为什么 gcc 寻找 _snprintf 而不是 snprintf?还是我走错了路,这是否与 gcc 为模板参数绑定所做的两部分名称查找有关?(ala 10.8.2, http: //idlebox.net/2009/apidocs/gcc-4.4.1.zip/gcc-4.4.1/gcc_10.html#SEC315

4

2 回答 2

0

您是否使用 -ansi 编译标志?

使用 -ansi 通常表示您希望标头仅公开 C89 标准中提到的接口。但是C89没有描述snprintf

于 2013-04-04T18:06:59.390 回答
0

(还不能发表评论,所以我写这个作为答案)。

关于您的第二个问题:这不太可能与两阶段名称查找有关。错误消息只是说有一个非依赖的未定义 smybol ( _snprintf)。

好的,为什么会这样?错误消息是 about _snprintf,而不是实际使用snprintf的 in writer.h,所以如果我不得不猜测我会说#define snprintf _snprintf在包含 STL 标头之前还有一些其他代码通过重新定义该名称。你的代码中有类似的东西吗?如果可能,请将其删除。

其他一些可以尝试的事情:如果可能的话,将包含writer.h移到文件顶部(即在重新定义 of 之前snprintf)。如果不可能,请尝试#undef snprintf在包含writer.h.

此外,单独这样的重新定义会导致我的机器上出现不同的错误。为了澄清这一点:您的系统上如何定义预处理器符号_GLIBCXX_USE_C99

如果这没有帮助,则需要更多信息。然后您能否发布完整的错误消息(也许是一个最小的重现示例)?

于 2013-04-09T07:17:56.593 回答