Остановка компилятора от генерации ошибок в коде C ++ с устаревшим кодом C - PullRequest
0 голосов
/ 08 сентября 2011

Я портирую устаревшую программу на C на C ++.Тем не менее, компилятор не устраивает и требует дополнительных типов типов для C ++.Например, у меня есть эта функция ...

 void foreach_element_in_patch(Patch *patch, void (*func)(), 
long arg1, long process_id);

В исходном коде C она используется следующим образом ...

 foreach_element_in_patch( patch, display_interactions_in_element, 
mode, process_id );

Однако для C ++ мне нужно выполнить typecastвторой аргумент, который запрещает компилятору генерировать ошибку.

 foreach_element_in_patch( patch, (void (*)())display_interactions_in_element, 
mode, process_id );

Ошибка, сгенерированная компилятором, следующая ...

invalid conversion from ‘void (*)(Patch*, long int, long int)’ to ‘void (*)()’

Теперь есть способ задатькомпилятор не генерирует ошибки для таких вещей.Я пытался добавить к этой функции префикс extern "C", но компилятор C ++ все равно не рад.Мои приложения загружены с таким кодом, и у меня нет времени, чтобы настроить так много кода.

Ответы [ 4 ]

6 голосов
/ 08 сентября 2011

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

Чтобы ваш код работал, вам необходимо:

  1. Создать новую функциюэто вызывает display_interactions_in_element с разумными значениями по умолчанию.
  2. Или используйте лямбда без захвата и без аргументов, которая делает то же самое (хотя она может еще не поддерживаться вашим компилятором).

Обратите внимание, что если ваш код пытается вызвать эту функцию так, как если бы он принял аргументы позже, это означает, что код в корне нарушен.

5 голосов
/ 08 сентября 2011

Да, есть способ. Скомпилируйте ваш код как C.

C ++ имеет более строгие правила безопасности типов и требует от вас явного приведения типов, которые могут быть неявно преобразованы в C.

Таким образом, либо скомпилируйте код как C, либо внесите изменения, необходимые для того, чтобы код был действительным C ++, и скомпилируйте его как C ++.

Вы должны быть в состоянии скомпилировать ваши файлы C как C, ваши файлы C ++ как C ++, а затем связать их вместе без проблем.

Но когда вы попытаетесь скомпилировать ваши C-файлы как C ++, компилятор скажет вам, если ваш код не является допустимым C ++.

3 голосов
/ 09 сентября 2011

Я думаю, что ваша ошибка связана с тем, что сигнатура функции имеет разное значение в C и C ++.Спецификация второго параметра

void (*func)()

в C означает «функцию с неизвестным числом и типом параметров», а в C ++ - «функцию без аргументов».Так что они совершенно разные, и это must crash.

Ошибка не в отсутствии безопасности типов C, а в вашем коде.Не делай этого.Используйте строгие прототипы, даже на C. Правильная спецификация параметров для обоих языков - просто

void (*func)(Patch*, long int, long int)

и все, и все просто слепо взламывает.

0 голосов
/ 09 сентября 2011

Самое простое, что нужно сделать, это изменить прототипы функций и заголовки, чтобы объявить правильный тип указателя функции. Так, например, для

void foreach_element_in_patch(Patch *patch, void (*func)(), 
 long arg1, long process_id);

Мне просто нужно изменить его на

void foreach_element_in_patch(Patch *patch, void (*)(Patch*, long int, long int), 
 long arg1, long process_id);

Вместо внесения изменений при каждом вызове функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...