Я получаю следующую ошибку при попытке сборки на 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: note: (если вы используете «-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.
Как я понимаю ответ на вопрос выше, включение cstdio должно объявить символ snprintf в стандартном пространстве имен. Итак, я подумал включить stdio.h, чтобы получить символ, определенный в глобальном пространстве имен. Одна и та же ошибка компиляции, независимо от того, включаю ли я cstdio, stdio.h или оба файла (что мне не нужно было делать)
Мой вопрос состоит из двух частей: почему gcc ищет _snprintf, а не snprintf? Или я не на том пути, и связано ли это с поиском имен из двух частей, который gcc выполняет для привязки параметров шаблона? (аля 10.8.2, http://idlebox.net/2009/apidocs/gcc-4.4.1.zip/gcc-4.4.1/gcc_10.html#SEC315)
Вы используете флаг компиляции -ansi?
Использование -ansi обычно говорит, что вы хотите, чтобы заголовки отображали ТОЛЬКО
интерфейсы, упомянутые в стандарте C89. Но С89 не описал
snprintf
(Пока не могу комментировать, поэтому я пишу это как ответ).
Относительно вашего второго вопроса: вряд ли это связано с поиском двухфазного имени. Сообщение об ошибке просто говорит, что есть независимый неопределенный smybol (_snprintf
).
Хорошо, почему это происходит? Сообщение об ошибке о _snprintf
, а не на самом деле используется snprintf
в writer.h
поэтому, если бы мне пришлось угадывать, я бы сказал, что есть какой-то другой код, переопределяющий это имя через #define snprintf _snprintf
перед включением заголовков STL. Есть ли что-то подобное в вашем коде? Если возможно, удалите его.
Некоторые другие вещи, которые нужно попробовать: переместить включение writer.h
в начало файла (то есть до переопределения snprintf
происходит), если это возможно. Если это невозможно, попробуйте #undef snprintf
перед включением writer.h
,
Кроме того, такое переопределение само по себе приводит к другой ошибке на моей машине. Чтобы уточнить это: как символ препроцессора _GLIBCXX_USE_C99
определено в вашей системе?
Если это не поможет, нужна дополнительная информация. Не могли бы вы опубликовать полное сообщение об ошибке (и, возможно, минимальный пример для воспроизведения)?