#c
Вопрос:
Недавно я получил просьбу от знакомого помочь в создании решения на C после того, как их разработчик, к сожалению, скончался. Я относительно новичок в C и не совсем понимаю, что делают следующие строки.
Этот код взят из настроенной версии dcraw.cpp библиотека Дэйва Коффина.
МАКРОС определяется как
#define CLASS
Вызываемый метод выглядит следующим образом
void CLASS merror (void *ptr, char *where)
{
if ( ptr ) return;
//fprintf (stderr,_("%s: Out of memory in %sn"), ifname, where);
sprintf (PSstring(),"%s: Out of memory in %sn", ifname, where);
PSputDiag ();
longjmp (failure, 1);
}
И вызов метода выглядит так
merror (fimg, "wavelet_denoise()");
При попытке скомпилировать код я получаю около 1800 ошибок, 258 из которых похожи на следующие.
C2664 ‘void merror(void *,char *)’: не удается преобразовать аргумент 2 из ‘const char [15]’ в ‘char *’ Фотосессия 5 C:UserssourceprojectnameMVDcraw.cpp 991
Я довольно долго искал, чтобы выяснить, что происходит, но так как я даже не знаю, что делает вызов метода, я не смог найти ничего, что имеет отношение к делу.
Любая помощь будет очень признательна.
Комментарии:
1.
CLASS
это не имеет значения."wavelet_denoise()"
является постоянным строковым литералом иmerror
ожидает неконстантности. Изменитеchar *where
наchar const *where
. Такжеlongjmp
в программе на C есть большой красный флаг «…Никакие деструкторы для автоматических объектов не называются….» en.cppreference.com/w/cpp/utility/program/longjmp.2. Измените прототип на
void CLASS merror(void *ptr, const char *where)
. Вы можете полностью опустить этуCLASS
часть, если только она не нужна какому-либо другому инструменту или утилите. (Некоторые компиляторы разрешали передавать символьные строки вchar *
качестве расширения.)
Ответ №1:
Макрос
#определить КЛАСС
не имеет никакого отношения к вашей ошибке. После расширения макроса функция:
void merror (void *ptr, char *where)
{
if ( ptr ) return;
//fprintf (stderr,_("%s: Out of memory in %sn"), ifname, where);
sprintf (PSstring(),"%s: Out of memory in %sn", ifname, where);
PSputDiag ();
longjmp (failure, 1);
}
То есть макрос заменяется ничем.
Код, по-видимому, был написан до C 11. От cppreference…
до C 11:
Строковые литералы преобразуются и присваиваются неконстантным символам* или wchar_t*, чтобы быть совместимыми с C, где строковые литералы имеют типы char[N] и wchar_t[N]. Такое неявное преобразование не рекомендуется.
начиная с C 11:
Строковые литералы не преобразуются и не могут быть назначены для неконстантной диаграммы*. Если требуется такое преобразование, необходимо использовать явное приведение (например, const_cast).
Преобразование строковых литералов в char*
никогда не было в порядке, но только с C 11 это ошибка. Если вы используете C 17, вы можете использовать std::string::data()
:
std::string where{"wavelet_denoise()"};
merror (fimg, where.data());
На самом деле лучше было бы изменить метод, как предложено в комментарии Ричарда Криттена, чтобы взять const char* where
А.