¿Funciones selectivamente en línea (para fines de depuración)?

Lo que me encantaría tener es una configuración de compilación donde las funciones son no en línea, excepto algunas funciones seleccionadas (que pueden o no estar en línea, eso dependería del compilador).

Aún mejor sería algún tipo de "nivel de inserción", donde podría especificar dicho nivel para cada función, más un nivel mínimo al construir, y solo las funciones por encima del nivel mínimo podrían estar en línea. Sé que no hay una solución estándar para esto, pero los trucos específicos del compilador serían igualmente bienvenidos.

Me gustaría poder recorrer paso a paso la mayoría de mis funciones no en línea en un depurador, pero algunas de ellas deberían estar en línea, en parte por razones de rendimiento y en parte para evitar pilas de llamadas locamente profundas. El código implica una metaprogramación de plantilla bastante desagradable, pero esa parte está casi terminada, así que me gustaría concentrarme en el resto. Por lo tanto, sería bueno tener las funciones que pertenecen a los metaprogramas de plantilla en línea, pero no las otras funciones en línea.

¿Hay alguna manera de lograr algo como esto?

preguntado el 12 de junio de 12 a las 20:06

Puede usar macros de preprocesador, pero lo que está describiendo no se puede controlar en tiempo de ejecución. -

Y lo mismo se aplica a las plantillas. Eso también se corrige en tiempo de compilación. -

Gracias por las respuestas. No quiero controlar esto en tiempo de ejecución. Sin embargo, no estoy seguro de lo que quiere decir, ¿cómo usaría las macros aquí? En lugar de funciones en línea? Que me gustaría evitar. Sería bueno poder compilar con todo en línea (compilación de depuración estándar) o solo algunas de las funciones; controlado por un interruptor de compilador o algo así. -

2 Respuestas

Dependiendo de su compilador, sí. Para g ++, lo siguiente funcionará:

void foo() __attribute__ ((noinline));
void foo() __attribute__ ((always_inline));

En MSVC++:

__declspec(noinline) void foo();
__forceinline void foo();

Tenga en cuenta que g ++ requiere que los atributos se apliquen solo a prototipos, no a definiciones. Entonces, si su función es solo de definición (sin prototipo separado), entonces debe crear un prototipo para aplicar el atributo. MSVC no tiene este requisito.

__forceinline específicamente tiene algunas excepciones. Asegúrese de leerlos detenidamente para saber si tendrá o no algún efecto en su situación particular. g++ no documenta ninguna excepción a la always_inline atributo, pero algunas cosas son evidentes (incrustar una llamada a un método virtual solo funcionará cuando el método se llame estáticamente, por ejemplo).

Puedes generalizar esto con macros:

#ifdef _MSC_VER
 #define NOINLINE(x) __declspec(noinline) x
 #define INLINE(X) __forceinline x
#else
 #ifdef __GNUC__
  #define NOINLINE(x) x __attribute__ ((noinline))
  #define INLINE(x) x __attribute__ ((always_inline))
 #else
  #error "I don't know how to force inline/noinline on your compiler."
 #endif
#endif

INLINE(void foo());
NOINLINE(void foo());

Respondido el 12 de junio de 12 a las 21:06

Gracias. ¿__forceinline / always_inline anularía los modificadores del compilador relevantes (p. ej., /Ob0 en MSVC)? - imre

@imre Creo que ese es su propósito, anular todos y cada uno de los demás procesos de toma de decisiones que el compilador usaría para decidir si alinear o no una función en particular. - cdhowie

@imre: Desde los docs, No: "Incluso con __forceinline, el compilador no puede codificar en línea en todas las circunstancias. El compilador no puede alinear una función si: ... La función o la persona que llama se compila con /Ob0 (la opción predeterminada para compilaciones de depuración)."- ildjarn

@ildjarn Supongo que no bajé la página lo suficiente al leer. Bueno, esto es al menos lo más cerca que uno puede llegar a tener un control preciso sobre la inserción de funciones. - cdhowie

Si hay un conjunto de funciones que desea inlined, puedes #define alguna macro (asumiendo GCC o Clang) para __attribute__(__always_inline__), que lo hará

  1. Siempre en línea la función
  2. dar un error de compilación si eso no es posible por razones técnicas.

Respondido el 12 de junio de 12 a las 21:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.