infinitos etiquetas definicion ciclos c++ c goto jump-table

c++ - etiquetas - ciclos infinitos



¿Cómo almacenar etiquetas goto en una matriz y luego saltar a ellas? (11)

¿Podrías usar punteros de función en lugar de goto?

De esa manera puede crear una serie de funciones para llamar y llamar a la apropiada.

Quiero declarar una serie de "jumplabels".

Entonces quiero saltar a una "etiqueta de salto" en esta matriz.

Pero no tengo ni idea de cómo hacer esto.

Debería verse como el siguiente código:

function() { "gotolabel" s[3]; s[0] = s0; s[1] = s1; s[2] = s2; s0: .... goto s[v]; s1: .... goto s[v]; s2: .... goto s[v]; }

¿Alguien tiene una idea de cómo realizar esto?


En la norma C simple, esto no es posible por lo que sé. Sin embargo, hay una extensión en el compilador GCC, documentada aquí , que hace esto posible.

La extensión introduce al nuevo operador && , para tomar la dirección de una etiqueta, que luego se puede usar con la declaración goto .


Es posible con la característica GCC conocida como " etiquetas como valores ".

void *s[3] = {&&s0, &&s1, &&s2}; if (n >= 0 && n <=2) goto *s[n]; s0: ... s1: ... s2: ...

¡Solo funciona con GCC!


Es posible que desee ver setjmp / longjmp.


La optimización de compiladores (incluido GCC) compilará una instrucción de cambio en una tabla de salto (haciendo una instrucción de cambio exactamente tan rápido como lo que estás tratando de construir) SI se cumplen las siguientes condiciones:

Los casos de cambio (números de estado) comienzan en cero.

Sus cajas de cambio están estrictamente aumentando.

No omites ningún número entero en los casos de cambio.

Hay suficientes casos en los que una tabla de saltos es en realidad más rápida (un par de docenas de comparaciones y gotos en el método de verificación de cada caso para tratar con las instrucciones de cambio es en realidad más rápido que una tabla de saltos).

Esto tiene la ventaja de permitirle escribir su código en C estándar en lugar de confiar en una extensión de compilador. Funcionará igual de rápido en GCC. También funcionará igual de rápido en la mayoría de los compiladores de optimización (sé que el compilador de Intel lo hace; no estoy seguro de las cosas de Microsoft). Y funcionará, aunque más lento, en cualquier compilador.


No hay una forma directa de almacenar direcciones de código para saltar a C. ¿Qué hay de usar el interruptor?

#define jump(x) do{ label=x; goto jump_target; }while(0) int label=START; jump_target: switch(label) { case START: /* ... */ case LABEL_A: /* ... */ }

Puede encontrar un código similar producido por cada generador de analizador / máquina de estado sin pila. Tal código no es fácil de seguir, así que, a menos que sea un código generado o su problema sea descrito más fácilmente por la máquina de estado, recomendaría no hacerlo.


No puede hacerlo con un goto: las etiquetas deben ser identificadores, no variables o constantes. No puedo ver por qué no querría usar un interruptor aquí; es probable que sea igual de eficiente, si eso es lo que le preocupa.


Para eso están las instrucciones de switch .

switch (var) { case 0: /* ... */ break; case 1: /* ... */ break; default: /* ... */ break; /* not necessary here */ }

Tenga en cuenta que el compilador no lo traduce necesariamente en una tabla de salto.

Si realmente desea construir la tabla de salto usted mismo, puede utilizar una matriz de punteros de función.


Para una respuesta simple, en lugar de forzar a los compiladores a hacer cosas realmente estúpidas, aprenda las buenas prácticas de programación.


Tokenizer? Esto parece que gperf fue hecho para. No realmente, échale un vistazo.


goto necesita una etiqueta en tiempo de compilación.

A partir de este ejemplo, parece que está implementando algún tipo de máquina de estado. Más comúnmente se implementan como una construcción de caso de conmutación:

while (!finished) switch (state) { case s0: /* ... */ state = newstate; break; /* ... */ }

Si necesita que sea más dinámico, use una serie de punteros de función.