Entiendo que inline
en sí mismo es una sugerencia para el compilador y, a su discreción, puede o no incluir la función en línea, y también producirá un código de objeto enlazable.
Creo que static inline
hace lo mismo (puede o no estar en línea) pero no producirá un código de objeto vinculable cuando esté en línea (ya que ningún otro módulo podría vincularlo).
¿Dónde extern inline
encaja en la imagen?
Suponga que quiero reemplazar una macro de preprocesador por una función en línea y requiero que esta función se inserte (por ejemplo, porque usa las macros __FILE__
y __LINE__
que deberían resolverse para la persona que llama pero no esta función llamada). Es decir, quiero ver un error del compilador o del enlazador en caso de que la función no se inserte. ¿Hace extern inline
esto? (Supongo que, si no es así, no hay forma de lograr este comportamiento más que seguir con una macro).
¿Existen diferencias entre C ++ y C?
¿Existen diferencias entre los diferentes proveedores y versiones de compiladores?
fuente
extern inline
está sujeta a la regla de una definición, y esta es la definición. Pero si las heurísticas de optimización definidas por la implementación siguen la recomendación de utilizar lainline
palabra clave como una sugerencia de que "las llamadas a la función sean lo más rápidas posible" (ISO 9899: 1999 §6.7.4 (5),extern inline
cuentaCreo que malinterpretas __FILE__ y __LINE__ en base a esta declaración:
Hay varias fases de compilación y el preprocesamiento es la primera. __FILE__ y __LINE__ se reemplazan durante esa fase. Entonces, para cuando el compilador pueda considerar la función para la inserción, ya habrá sido reemplazada.
fuente
Parece que estás intentando escribir algo como esto:
y con la esperanza de que se impriman valores diferentes cada vez. Como dice Don, no lo hará, porque el preprocesador implementa __FILE__ y __LINE__, pero el compilador implementa en línea. Entonces, desde donde llame a printLocation, obtendrá el mismo resultado.
La única forma de que esto funcione es hacer de printLocation una macro. (Sí, lo sé...)
fuente
La situación con inline, static inline y extern inline es complicada, sobre todo porque gcc y C99 definen significados ligeramente diferentes para su comportamiento (y presumiblemente C ++ también). Puede encontrar información útil y detallada sobre lo que hacen en C aquí .
fuente
Las macros son su elección aquí en lugar de las funciones en línea. Una rara ocasión en la que las macros dominan las funciones en línea. Intente lo siguiente: escribí este código "MACRO MAGIC" y debería funcionar. Probado en gcc / g ++ Ubuntu 10.04
Para varios archivos, defina estas macros en un archivo de encabezado separado que incluya lo mismo en cada archivo c / cc / cxx / cpp. Siempre que sea posible, prefiera las funciones en línea o los identificadores constantes (según lo requiera el caso) sobre las macros.
fuente
En lugar de responder "¿qué hace?", Respondo "¿cómo hago para que haga lo que quiero?" Hay 5 tipos de inserción, todos disponibles en GNU C89, C99 estándar y C ++:
siempre en línea, a menos que se tome la dirección
Añadir
__attribute__((always_inline))
a cualquier declaración, luego use uno de los casos siguientes para manejar la posibilidad de que se tome su dirección.Probablemente nunca debería usar esto, a menos que necesite su semántica (por ejemplo, para afectar el ensamblaje de cierta manera, o para usar
alloca
). El compilador generalmente sabe mejor que usted si vale la pena.en línea y emitir un símbolo débil (como C ++, también conocido como "simplemente haz que funcione")
Tenga en cuenta que esto deja un montón de copias del mismo código por ahí, y el enlazador elige una arbitrariamente.
en línea, pero nunca emite ningún símbolo (dejando referencias externas)
emitir siempre (para una TU, para resolver lo anterior)
La versión insinuada emite un símbolo débil en C ++, pero un símbolo fuerte en cualquier dialecto de C:
O puede hacerlo sin la pista, que emite un símbolo fuerte en ambos idiomas:
Por lo general, sabe en qué idioma es su TU cuando proporciona las definiciones y probablemente no necesite mucha inserción.
en línea y emitir en cada TU
Para todos estos, excepto
static
uno, puede agregar unavoid foo(void)
declaración arriba. Esto ayuda con la "mejor práctica" de escribir encabezados limpios y luego#include
crear un archivo separado con las definiciones en línea. Entonces, si usa líneas de estilo C,#define
algunas macros de manera diferente en una TU dedicada para proporcionar las definiciones fuera de línea.¡No olvide
extern "C"
si el encabezado se puede usar tanto desde C como desde C ++!fuente
nm
equivalente.