1. Razones para introducir la palabra clave inline
En C/C++, para resolver el problema de que algunas funciones pequeñas llamadas con frecuencia consumen una gran cantidad de espacio de pila (memoria de pila), se introduce especialmente elinlinemodificador, que se denomina función inline.
El espacio de pila se refiere al espacio de memoria donde se colocan los datos locales del programa (es decir, los datos dentro de las funciones).
En el sistema, el espacio de pila es limitado. Si se usa con frecuencia y en grandes cantidades, puede causar problemas de errores en el programa debido a espacio de pila insuficiente. Por ejemplo, el resultado final de una llamada recursiva en bucle infinito de una función es agotar el espacio de memoria de pila.
A continuación veamos un ejemplo:
Ejemplo
El ejemplo anterior es el uso estándar de la función inline. El uso delinlinemodificador trae beneficios que no se ven superficialmente. En realidad, el trabajo interno es que en cadafordentro del bucle, cualquier llamada adbtest(i)se reemplaza por(i%2>0)?"impar":"par", de esta manera se evita el consumo causado por la apertura repetida de memoria de pila al llamar a la función con frecuencia.
2. Limitaciones del uso de inline
inlineSu uso tiene limitaciones. inline solo es adecuado para funciones con código simple dentro del cuerpo de la función. No puede contener estructuras de control de flujo complejas como while, switch, y además la función inline en sí no puede ser una función recursiva directa (es decir, una función que se llama a sí misma internamente).
3. inline es solo una sugerencia para el compilador
inlineLa función inline es solo una sugerencia para el compilador, por lo que al final, si realmente se puede inlinear, depende del compilador. Si considera que la función no es compleja y puede expandirse en el punto de llamada, entonces realmente se inlineará. No significa que declararla como inline la haga inline; declararla inline es solo una sugerencia.
4. Se recomienda colocar la definición de la función inline en el archivo de cabecera
En segundo lugar, debido a que la función inline debe expandirse en el punto de llamada,el compilador debe poder ver la definición de la función inline en todas partes; de lo contrario se convertiría en una llamada a una función no inline. Por lo tanto, esto requiere que cada archivo que llame a la función inline contenga ladefinición de la función inline。
Por lo tanto, colocar ladefinición de la función inlineen elarchivo de cabecerae implementarla allí es apropiado, ahorrándote la molestia de implementarla una vez en cada archivo.
La declaración y la definición deben ser consistentes:Si se implementa la función inline una vez en cada archivo, entonces es mejor asegurarse de que cada definición sea igual; de lo contrario, se provocará un comportamiento indefinido. Si las definiciones no son iguales en cada archivo, cuál expande el compilador dependerá del compilador específico. Por lo tanto, es mejor colocar ladefinición de la función inlineen elarchivo de cabecera.
5. Funciones miembro de una clase e inline
Definidasen la clase,las funciones miembroson por defectoinline. Si se proporciona la definición de la función dentro de la clase al definir la clase, por supuesto es mejor. Si no se proporciona la definición de la función miembro en la clase, pero se desea que la función sea inline, entonces fuera de la clase se debe agregarinline; de lo contrario se considera que no es inline.
Aunque colocar el cuerpo de definición de la función miembro dentro de la declaración de la clase brinda comodidad al escribir, no es un buen estilo de programación. El ejemplo anterior debería cambiarse a:
6. inline es una "palabra clave para la implementación"
La palabra claveinlinedebe colocarse junto con el cuerpo de definición de la función para que la función sea inline. Solo ponerinlinedelante de la declaración de la función no tiene ningún efecto.
Una función con el siguiente estiloFoono puede convertirse en función inline:
inline void Foo(int x, int y); // inline 仅与函数声明放在一起
void Foo(int x, int y){}
Mientras que una función con el siguiente estiloFoosí se convierte en función inline:
void Foo(int x, int y);
inline void Foo(int x, int y) {} // inline 与函数定义体放在一起
Por lo tanto, inline es unapalabra clave para la implementación, no una "palabra clave para la declaración". Generalmente, los usuarios pueden leer la declaración de la función, pero no pueden ver la definición de la función. Aunque en la mayoría de los libros de texto se agrega la palabra clave inline tanto en la declaración como en el cuerpo de definición de la función inline, creo queinline no debería aparecer en la declaración de la función. Aunque este detalle no afecta la funcionalidad de la función, refleja un principio básico del estilo de programación en C++/C de alta calidad:La declaración y la definición no deben confundirse. El usuario no tiene necesidad, ni debería saber si la función necesita ser inline.
7. Usa inline con precaución
Inline puede mejorar la eficiencia de ejecución de las funciones. ¿Por qué no definir todas las funciones como funciones inline? Si todas las funciones fueran inline, ¿sería necesaria la palabra clave "inline"?
Inline es a costa de laexpansión del código (copia), que simplemente ahorra la sobrecarga de la llamada a la función, mejorando así la eficiencia de ejecución de la función.
Si el tiempo de ejecutar el código dentro del cuerpo de la función es mayor en comparación con la sobrecarga de la llamada a la función, la ganancia de eficiencia será muy pequeña. Por otro lado, cada llamada a una función inline requiere copiar código, lo que aumentará la cantidad total de código del programa y consumirá más espacio de memoria.
No es recomendable usar inline en los siguientes casos:
(1) Si el código dentro del cuerpo de la funciónes relativamente largo, usar inline provocaráun costo alto de consumo de memoria。
(2) Si aparece unbucle, entonces el tiempo de ejecutar el código dentro del cuerpo de la función será mayor que la sobrecarga de la llamada a la función. Los constructores y destructores de clases fácilmente hacen que las personas malinterpreten que usar inline es más eficaz. Hay que tener cuidado de quelos constructores y destructores pueden ocultar algunos comportamientos,como ejecutar "silenciosamente" losconstructores y destructores de la clase base o de objetos miembro. Por lo tantono coloques casualmente el cuerpo de definición de los constructores y destructores en la declaración de la clase.Un buen compilador cancelará automáticamente el inline que no vale la pena, según el cuerpo de definición de la función (esto demuestra además que inline no debería aparecer en la declaración de la función).
8. Resumen
Las funciones inline no son una panacea para mejorar el rendimiento. Solo cuando lafunción es muy pequeñapuede lograr el efecto que deseamos; pero, si la función no es muy corta y se llama en muchos lugares, hará que el tamaño del ejecutable aumente.
Lo más molestoes cuando elcompilador rechaza el inline. En implementaciones antiguas, los resultados eran muy insatisfactorios. Aunque en las nuevas implementaciones ha habido grandes mejoras, todavía no son perfectas. Algunos compiladores son lo suficientemente inteligentes para señalar qué funciones se pueden inlinear y cuáles no, pero la mayoría no lo son tanto, por lo que se necesita nuestra experiencia para juzgar.¡Si las funciones inline no mejoran el rendimiento, evita usarlas!
Enlace original: https://www.cnblogs.com/fnlingnzb-learner/p/6423917.html