Quiero forzar que una pequeña función no se compile como función en línea, incluso si es muy simple. Creo que esto es útil para la depuración. ¿Hay alguna palabra clave para hacer esto?¿Es posible forzar que una función no esté en línea?
Respuesta
En Visual Studio 2010, __declspec(noinline)
indica al compilador que no inline una función miembro en particular, por ejemplo:
class X {
__declspec(noinline) int member_func() {
return 0;
}
};
edición: Además, al compilar con /clr
, funciona con atributos de seguridad nunca se inline (de nuevo, esto es específico de VS 2010).
No creo que sea útil en la depuración.
La documentación dice que es solo para funciones miembro: https://msdn.microsoft.com/en-us/library/kxybs02x.aspx. ¿Hay alguna manera de hacer que una función autónoma no esté en línea? –
Muchos compiladores pueden realizar en línea la unidad de traducción cruzada. Visual Studio lo ha tenido durante cinco años y creo que ahora GCC puede hacerlo, especialmente desde que el OP etiquetado como Visual C++, es una apuesta justa que su compilador puede hacer frente.
La forma más sencilla de hacerlo es tomar la dirección de la función y luego hacer algo que no tenga sentido, como llamarla o pasarla a una función de biblioteca externa/SO. El compilador no puede alinear ese tipo de función.
Por qué alguna vez querrías, IDK.
@comments:
Si el OP srsly, srsly necesita esto, entonces podría compilar como un lib y estáticamente enlazar con él.
Si bien tomar la dirección de una función requiere que el compilador proporcione una versión no en línea de la misma, no creo que se requiera para no incluirla en otros lugares. – sbi
Eso no impide que incluya una función. Como sbi correctamente señaló, solo producirá una versión no en línea. – wheaties
Estoy bastante seguro de que la documentación de VC++ dice que no alineará ninguna función en la que se tome su dirección. Sin embargo, ciertamente no puede moverlo entre unidades de traducción, y si no puede tomar su dirección, entonces la única manera de estar seguro es compilarlo en una lib externa. – Puppy
¿Es posible forzar que una función no esté en línea?
Ni siquiera intentaré responder esa pregunta, porque es irrelevante preocuparse por esto excepto por las dos razones que se detallan a continuación.
Inlining básicamente es
- una optimización que es casi transparente para que
- una manera de permitir que las funciones que se definirán en las cabeceras sin obtener errores de definición multpile
(Algunos podrían cambiar el orden de estos dos, pero me atengo a la orden tradicional.)
A menos que sea A) es absolutamente necesario define una función en algún encabezado o B) está perfilando y optimizando una pieza de código y sabe mejor que el compilador lo que debe incluirse y lo que no debería ser, la inserción no debería preocuparle.
Sin duda no debería ser una preocupación debido a la depuración. Su depurador debe (y en el caso de VC también lo hace) encargarse de eso por usted.
@sbi Soy uno de los downvoters. Una función real tiene un símbolo en el código objeto, ofrece varios beneficios sobre una paz de código en línea. Puede rastrearlos desde un depurador o un analizador de código dinámico. Con un generador de perfiles puede saber la cantidad exacta de tiempo dedicado a la función, es difícil cuando la paz del código se fusiona en otra paz de código más grande. Puede cambiar el nombre dinámicamente de la función, o incluso sustituir esta función por otra en el tiempo de ejecución. – Ben
@Ben: la depuración generalmente tiene lugar en el código creado para la depuración, y eso no debería tener funciones en blanco de todos modos. Para compilaciones de versiones, la alineación es solo una de las muchas distorsiones perturbadoras que el optimizador hace a su código. Y no delimitar una función para perfilar parece _absurd_, por decirlo suavemente. (Se trata de los analizadores de códigos dinámicos más comunes, ¿qué más hay?), Lo que deja el cambio de nombre de una función en tiempo de ejecución, lo que parece un concepto extraño, a menos que haga referencia al enlace tardío a libs cargados dinámicamente (.so, .dll). Ese es el único caso que puedo ver para "no" querer alinear una función. – sbi
@sbi: No es absurdo, no puede evaluar el costo de una función en línea. Por analizador de código dinámico me refiero a herramientas como valgrind purificar o asegurar ++. Sí, estaba pensando en un enlace o reenlazamiento tardío, lo uso en algún momento siguiendo el propósito. De todos modos, no sé qué quería Thomson, pero puede no ser irrelevante para él, por eso he votado negativamente. – Ben
Puede dividir la implementación de la clase entre un encabezado y un archivo cpp. si coloca la función fuera de la definición de clase, su pequeña función no estará en línea.
En algunos, pero no en todos los compiladores, esto funcionará. OTOH Tengo un problema con quien lo rechazó y ni siquiera dejé un comentario explicando por qué. –
Recuerde que la alineación es relevante en el sitio de la llamada a la función , la misma función se puede insertar en algunas situaciones y no en otra.
Si su función es visible fuera de la unidad de compilación a continuación, incluso si se trata de inline en todo los lugares actuales se consume, el cuerpo de la función todavía debe estar disponible para cualquier persona que quiera llamarlo posteriormente (mediante la vinculación con el archivo objeto).
Para que un sitio de llamada no esté en línea, puede usar un puntero a una función.
void (*f_ptr)(int); // pointer to function
volatile bool useMe = true; // disallow optimizations
if (useMe)
f_ptr = myFunc;
else
f_ptr = useOtherFunc;
f_ptr(42); // this will not be inlined
__declspec(noinline)
para VC++. A diferencia de la página man, esto parece funcionar para funciones independientes, y no creo haberlo usado nunca para una función miembro. Puede -aunque tenga en cuenta que nunca lo he hecho- querer considerar jugar con los indicadores de optimización también, de modo que solo las funciones inline
se consideren para la alineación, aunque, por supuesto, esto tiene un efecto global y es posible que no sea lo que usted desea.
__attribute__((noinline))
para gcc (y una serie de compiladores menos comunes que admiten la sintaxis del atributo gcc). Debo admitir que no creo haber usado esto alguna vez, pero parece estar allí.
(Por supuesto, estos dos estilos de anotación van en diferentes lugares, por lo que es un poco molesto para construir código que es aceptable para ambos.)
No estoy seguro de cómo cualquiera de éstos interactúan con el inline
C++ palabra clave; Solo los he usado para depurar (cuando solo quiero que una función en particular que no esté en línea no esté en línea después de la optimización) o cuando examino el código generado (y me confundo porque algo aleatorio está en línea).
funciona también para funciones de miembros. Una nota interesante a tomar es que parece hacer llamadas no en línea para contener funciones también (aunque de otra manera estarían en línea) - VS 2012 – Ghita
cómo verificar mediante cmake qué compilador utilizó: vC++ o gcc y hacer definir 'noinline'? – Andreyua
Simple: no permita que el compilador vea la definición de la función. Entonces no puede ser inline. Por supuesto, eso solo funciona si es su código.
Cuando se trata de depurar código de terceros ... sí, esto sería útil, especialmente si se puede borrar el código de terceros desde lejos. Cualquier persona que haya depurado el código que contiene mucha desreferencia compartida comparte lo que estoy diciendo.
Si es una función miembro de una clase, hágalo virtual.
No necesariamente funcionará; si el método se puede desvirtualizar, aún puede estar en línea. – Alice
- 1. ¿Qué significa que una función de C++ esté en línea?
- 2. ¿Es posible que ConcurrentHashMap esté en "punto muerto"?
- 3. ¿Es posible obtener objetos jquery de una cadena html que no esté en el DOM?
- 4. ¿Es posible forzar un tipo a una clase en Haskell?
- 5. línea después de que IFRAME no esté visible
- 6. ¿Es posible multiprocesar una función que devuelve algo en Python?
- 7. ¿es posible no devolver nada desde una función en python?
- 8. ¿Es posible escribir una función SQL que emita JSON?
- 9. ¿Es posible llamar a una función que no está en la ruta en MATLAB?
- 10. ¿Es posible "forzar detener" una aplicación que estoy depurando usando adb en la terminal?
- 11. ¿Es posible evitar que el botón de enviar se envíe hasta que DOM esté cargado?
- 12. $ .cookie no es una función
- 13. ¿Es posible tener una aplicación para iOS que no esté habilitada para ARC pero con algunos archivos de arco?
- 14. ¿No es una función?
- 15. matriz cuando no esté en una declaración
- 16. ¿Es posible definir una función local en una consulta TSQL?
- 17. ¿Es posible invocar una función después de que windows.location ha cargado una nueva URL?
- 18. ¿Es posible forzar automáticamente el modo SQLCMD en el script?
- 19. ¿Es posible crear una línea entre elementos en CSS3?
- 20. 'undefined' no es una función que evalúa el.click() en Safari
- 21. En Clojure, ¿es posible definir una función anónima dentro de una función anónima?
- 22. ¿Es posible crear pseudo styles en línea?
- 23. ¿Es posible ver el historial de una línea en SVN?
- 24. Forzar un salto de línea en una URL
- 25. ¿Es posible escribir una función varargs que envíe su lista de argumentos a otra función varargs?
- 26. ¿Es posible optimizar esta función?
- 27. ¿Es posible forzar a una aplicación Java existente a usar no más de x núcleos?
- 28. ¿Es posible tener una línea por cada bloque en Ruby?
- 29. ¿Es posible (recomendado) tener un api-project puro que esté separado de la implementación real?
- 30. Haciendo que una DLL COM esté accesible
El depurador puede manejar perfectamente las funciones en línea. No hay necesidad de evitar la inflación debido a eso. – jalf
No realmente. Excelente manera de colgar el depurador durante muchos minutos mientras establece miles de puntos de interrupción. –
Al pasar a través del código optimizado (que básicamente tiene que hacer a nivel de lenguaje ensamblador) a veces es agradable ver llamadas a funciones para que pueda seguir donde se encuentra y pasarlas de una vez, ya que la vista del compilador "simple" puede no ser tuyo. (El depurador puede funcionar bien con todo esto, pero es el operador de la computadora el que realmente tiene que hacer el trabajo ...) –