0

I'm attempting to use a c library in a c++ implementation, and I get errors often having to do with "cantidate function not viable," and it appears to think that the function in the library will not function with the arguments presented in my code. The thing is, my code is literally an old implementation (in c) that works perfectly fine when compiled in c. Is there a way to make this compile as a part of my c++ environment?

Here are the errors I get:

testbed/des-lsr_routinglogic.cpp:20:27: error: no matching function for call to 'dessert_periodic_add'
periodic_refresh_nh = dessert_periodic_add(refresh_list, NULL, NULL, &refresh_neighbor_t);
                      ^~~~~~~~~~~~~~~~~~~~
/usr/local/include/dessert.h:880:21: note: candidate function not viable: no known conversion from 'dessert_per_result_t ()' to 'dessert_periodiccallback_t *' (aka 'dessert_per_result_t (*)(void *, struct
  timeval *, struct timeval *)') for 1st argument
dessert_periodic_t* dessert_periodic_add(dessert_periodiccallback_t* c, void* data, const struct timeval* scheduled, const struct timeval* interval);
                ^

from this line of code code:

periodic_refresh_nh = dessert_periodic_add(refresh_list, NULL, NULL, &refresh_neighbor_t);

using this excerpt of the library:

dessert_periodic_t* dessert_periodic_add(dessert_periodiccallback_t* c, void* data,     const struct timeval* scheduled, const struct timeval* interval);
dessert_periodic_t* dessert_periodic_add_delayed(dessert_periodiccallback_t* c, void* data, int delay);
int dessert_periodic_del(dessert_periodic_t* p);
void dessert_register_ptr_name(void* ptr, const char* name);
const char* dessert_ptr2name(void* ptr);

I think the compiler output should be self evident to anyone experienced in combining c/c++ but it looks like gibberish to me D:

EDIT

Thank you, it was pointed out to me I left out some important definitions; The definition of refresh_list:

 dessert_per_result_t refresh_list(void *data, struct timeval *scheduled, struct timeval *interval) {
pthread_rwlock_wrlock(&pp_rwlock);
node_neighbors_t *neighbor = dir_neighbors_head;
while (neighbor) {
    if (neighbor->entry_age-- == 0) {
        node_neighbors_t* el_to_delete = neighbor;
        HASH_DEL(dir_neighbors_head, el_to_delete);
        free(el_to_delete);
    } else {
        neighbor->weight = 1;
    }
    neighbor = neighbor->hh.next;
}
pthread_rwlock_unlock(&pp_rwlock);
return 0; }

The definition of dessert_per_result_t:

 typedef enum _dessert_periodic_results { DESSERT_PER_KEEP = 0, DESSERT_PER_UNREGISTER = 1 } dessert_per_result_t;

dessert_periodiccallback_t is defined oddly; I will try to post it.

Charles
  • 50,943
  • 13
  • 104
  • 142
KeximusMaximus
  • 30
  • 1
  • 10

3 Answers3

2

C++ is stricter about function declarations than C. In this case, the function refresh_list is declared as dessert_per_result_t refresh_list(), but the first argument to dessert_periodic_add must be a pointer to a function with explicitly specified parameter types.

The best way to fix this would be to add a complete declaration of refresh_list, matching what dessert_periodic_add expects, in place of the abbreviated declaration of it.

David Foerster
  • 1,461
  • 1
  • 14
  • 23
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • Thanks to David Foerster for the correction. I was scrolling back and forth on a small device to copy text and compose an answer. – Eric Postpischil Jun 10 '13 at 13:05
  • Now I just need to ask the creator of the library what in the hell I should pass as params in a function I don't know when I want to call without global variables... oh, c... – KeximusMaximus Jun 10 '13 at 13:07
  • @GreyNewell: Global variables are not an issue. The parameter type is. The parameter type is shown: `dessert_periodic_add` expects a pointer to a function taking two parameters, the first a pointer to `void` and the other two pointers to `struct timeval *`, and returning `dessert_per_result_t`. So `refresh_list` should be declared as `dessert_per_result_t refresh_list(void *, struct timeval *, struct timeval *)`. – Eric Postpischil Jun 10 '13 at 15:09
0

The compiler message shows that the compiler is of the opinion that refresh_list is a function that takes no arguments and returns a dessert_per_result_t.

The definition you posted disagrees.

This suggests that there is a separate declaration of refresh_list that is inconsistent with the definition.

Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157
0

The declaration of refresh_list shown in the error message is this:

dessert_per_result_t refresh_list();

This means two different things in C++ and C.

In C++, it means that refresh_list takes zero arguments.

In C, it means that refresh_list takes an unspecified number of arguments of unspecified types.

Hence why it worked in C, but in C++ a pointer to refresh_list is not permitted where a pointer to dessert_per_result_t(void *, struct timeval *, struct timeval *) is expected.

See also:

Community
  • 1
  • 1
Oktalist
  • 14,336
  • 3
  • 43
  • 63