Доступ к адресу метки вне функции

#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;
}