2015-08-20 4 views
2

Итак, я пытаюсь сохранить ответ от HTTP-запроса libcURL в C-строку, которая будет проанализирована позже. Код ответа написан полностью на C, тогда как все остальное находится на C++ и с любым другим компилятором C++, он должен работать нормально. Но когда я пытаюсь скомпилировать, даже если я даю аргументы «-x c», за которыми следует имя файла, я получаю эти конкретные ответы.Ошибка: присвоение char * из несовместимого типа void *

g++ main.cpp -x c cJSON.c -x c respbuffer.c -lcurl -lm 

./respbuffer.c:14:9: error: assigning to 'char *' from incompatible type 'void *' 
    s->ptr = malloc(s->len+1); 
     ^~~~~~~~~~~~~~~~~ 
./respbuffer.c:23:9: error: assigning to 'char *' from incompatible type 'void *' 
    s->ptr = realloc(s->ptr, new_len+1); 
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~ 

Как ни странно, эта ошибка появляется только при компиляции с помощью g ++. Если я использую gcc, он работает нормально, и он работает достаточно гладко. Для любопытных я написал все в Xcode, и я компилирую GCC 4.2.1.

+1

В C это было бы хорошо ... но на C++ вам нужно указать правильный тип указателя. – Dmitri

+1

Возможно, вы должны скомпилировать свои источники C отдельно от своего C++, а затем связать файлы объектов после этого. – Dmitri

+0

Обычно не удается скомпилировать несколько исходных файлов в одном вызове компилятора, особенно когда они находятся на нескольких языках. Я думаю, что большинство людей собирали ваши файлы с четырьмя командами: один для g ++ для компиляции кода на C++, два для gcc для компиляции файлов C и, наконец, еще один вызов g ++ для связывания трех объектных файлов с библиотеками и создания исполняемый файл. –

ответ

5

Это происходит из-за того, что C довольно размазан типами, а C++ - строгим. malloc() возвращает void *, поэтому, чтобы использовать его как char *, вам нужно его отбросить.

+0

Но почему он компилируется как C++ в первую очередь? Должен ли параметр '-x c' гарантировать, что он скомпилирован как C? Я думаю * это ключ к этому вопросу, но вы не обращались к нему. –

+0

Я думаю, g ++ запутался, поскольку первый файл - cpp. Тем не менее, я не являюсь экспертом в настройках командной строки g ++. Я бы предложил прекратить компиляцию и соединение в одной команде и просто скомпилировать каждый файл по отдельности, а не связывать их вместе. Это устранит необходимость в специальных переключателях. – SergeyA

+0

Я бросил его с помощью (char *), и он отлично работал. Спасибо. – hudspero

2

В C функция malloc возвращает блок памяти в куче void*. В C это все нормально, потому что void* неявно литой в char*. Но на C++ это запрещено, поэтому вам нужно явно его бросить.

Так что в этом случае правильный код:

s->ptr = static_cast<char*>(malloc(s->len+1)); 
+0

Но опции '-x c' в командной строке должны сообщать компилятору, что он обрабатывает файл как C, правильно? Я думаю, что любой ответ на этот вопрос должен касаться параметров командной строки, а не просто различий языка между C и C++. –

0

Вы не должны использовать ++ компилятор C для компиляции кода C. Эти два языка отличаются друг от друга, и код, который является правильным в C, может безболезненно ошибочно работать на C++.

Добавление приведения в ваш код маскирует проблему; даже если он пока работает, вы действительно не знаете, что еще может произойти.

В моей системе -x c вызывает g++, чтобы вызвать C-компилятор. Возможно, у вас есть версия g ++, которая не поддерживает этот переключатель, или, возможно, g++ является псевдонимом для другого компилятора в вашей системе.

Если вы не можете получить -x c, пожалуйста, используйте gcc в качестве компилятора вместо g++. (Вам нужно будет использовать отдельные вызовы для файлов C, чем для файлов C++, а затем шаг ссылки).

+0

Если я скомпилирую файлы C с помощью 'gcc', тогда используйте' g ++ 'для компиляции' main.cpp' и '.o' файлов из компиляции' gcc', это сработает? – hudspero

+0

@hudspero да, это должно работать ... Я предложил это в комментарии вчера. – Dmitri

Смежные вопросы