#c
#c
Вопрос:
Я пишу «потоковый интерпретатор», используя вычисленный goto. Как мне инициализировать таблицу поиска адресов, чтобы она была видна из разных функций без дополнительных затрат времени выполнения?
Адрес метки виден только в той же функции, а статическая таблица поиска инициализируется компилятором в разделе данных без затрат времени выполнения при каждом вызове. Но он виден только в той же функции, и я хочу иметь другую функцию, чтобы иметь к ней доступ, например, для кэширования адресов и сохранения поисковых запросов в коде основного интерпретатора. Я могу взять указатель на эту таблицу и сохранить его где-нибудь, но это будет происходить при каждом вызове функции, и она будет вызываться часто. Да, это всего лишь один mov, но есть ли другой способ?
#include <stdio.h>
static void** table_ptr;
// how do i declare static variable and init it later once?
// Tried this. Generates runtime assigns at each call. Not unexpected
// static void** jumps_addr;
int main()
{
// labels are visible only inside the function
// generates runtime assigns at each call
// jumps_addr = (void* [10]){
// this initializes it in static data section, but name is only visible inside this function
static void* jumps_addr[10] = {
[1] = amp;amp;operation_print,
};
// want another way instead of this
table_ptr = jumps_addr;
// not optimize this
volatile int opcode = 1;
goto *jumps_addr[opcode];
return 0;
operation_print:;
printf("hellon");
return 0;
}
void do_some_preprocessing_work(void){
// want access to jumps_addr table here
// without having to store it somewhere
// [do something with table_ptr]
// this is to prevent optimization to explore what compiler does on godbolt.org
// because it will optimize away table_ptr entirely if not used
volatile i = 1;
i = table_ptr[i];
//actual code here will store labbel addrs into opcode struct to save table lookup at runtime
}
Комментарии:
1. Я не уверен, что я вполне понимаю, о чем вы спрашиваете, но если вы хотите, чтобы ваша таблица была инициализирована во время компиляции, тогда ее начальное содержимое должно быть указано в инициализаторе в его объявлении.
2. Проблема в том, что я инициализирую таблицу с помощью amp;amp;label , которая не видна вне функции, в которой она объявлена, поэтому я вынужден размещать объявление и инициализацию внутри этой функции, и это делает переменную невидимой извне. Я хотел бы каким-то образом обойти это, если это возможно
3. Объявите его в функции, сделайте его глобальным или передайте его функции. Какой еще есть вариант?
Ответ №1:
Решение может показаться неортодоксальным, но как насчет того, чтобы не использовать какие-либо функции, а только goto .
Вот так:
#include <stdio.h>
int main()
{
volatile int opcode;
static void* jumps_addr[10] = {
[0] = amp;amp;do_some_preprocessing_work,
[1] = amp;amp;operation_print
};
opcode = 0;
goto *jumps_addr[opcode];
return 1;
operation_print:
printf("hellon");
return 0;
do_some_preprocessing_work:
printf("jumps_addr[%i]n", opcode);
goto *jumps_addr[opcode];
return 1;
}