#c #function-pointers
#c #указатели на функции
Вопрос:
Я пишу программу, которая использует таблицу поиска для вызова функции или возврата константы на основе совпадения с ее именем. Каждый элемент в таблице определяется структурой tbl_entry_t:
typedef int (*fn_ptr_type)(int);
typedef struct {
char *str;
union {
fn_ptr_type fptr;
int number;
};
} tbl_entry_t;
Например, вот пример небольшой таблицы:
int squareFun (int x) { return x * x; }
int cubeFun (int x) { return x * x * x; }
int Hundred = 100;
char string0[] = "square";
char string1[] = "cube";
char string2[] = "hundred";
tbl_entry_t lookup_table[] = {
{ string0, squareFun },
{ string1, cubeFun },
{ string2, Hundred }
};
Я хочу смешать значения fn_ptr_type и int в таблице, и я включил объединение в структуру, чтобы попытаться достичь этого, но я все равно получаю предупреждение компилятора:
{ string2, Hundred }
warning: invalid conversion from 'int' to 'fn_ptr_type {aka int (*)(int)}'
Как правильно это сделать?
Комментарии:
1. как это связано с C ? это классический
C
вопрос. исправлены теги2.
{ string2, Hundred }
Итак, откуда вы знаете, что вы должны использоватьnumber
вместоfptr
? Эта таблица поиска имеет для меня мало смысла.3. «как это связано с C » Тем фактом, что для лучшего ответа может потребоваться C ?
Ответ №1:
Вам нужно указать элемент объединения, который вы хотите инициализировать — в противном случае по умолчанию инициализируется первый элемент:
tbl_entry_t lookup_table[] = {
{ string0, squareFun },
{ string1, cubeFun },
{ string2, .number = Hundred } // like this
};
например, в реальном времени: https://godbolt.org/z/9WobrG
Ответ №2:
ответ @code_fodder — это то, что я искал, но, к сожалению, в моем компиляторе GCC это выдает ошибку:
{ string2, .number = Hundred }
sorry, unimplemented: non-trivial designated initializers not supported
Однако я нашел уродливое решение, которое принимается и позволяет избежать предупреждения, которое заключается в записи:
tbl_entry_t lookup_table[] = {
{ string0, squareFun },
{ string1, cubeFun },
{ string2, (fn_ptr_type)Hundred } // workaround
};
Комментарии:
1.
non-trivial designated initializers not supported
Скомпилируйте свой код с помощью компилятора C, а не с помощью компилятора C .2. Какую версию GCC вы используете? — Я предполагаю, что он довольно старый?
3. похоже, это работает с gcc (c-compilation) начиная с версии 8.1 и далее: godbolt.org/z/so8PWK
4. Я использую avr-gcc версии 7.3.0.
5. @johnsondavies …. ах, если бы вы обновили одну версию до 8.1, вам не пришлось бы использовать свой ужасный хак — но, если это сработает … 🙂