Quelqu'un peut-il expliquer ce qu'ils sont et pourquoi j'en aurais besoin? Quel type d'applications suis-je en train de créer si j'ai besoin d'utiliser des intrinsèques?
Normalement, "intrinsèque" fait référence aux fonctions qui sont intégrées - c'est-à-dire la plupart des fonctions de bibliothèque standard que le compilateur peut/générera en ligne au lieu d'appeler une fonction réelle dans la bibliothèque. Par exemple, un appel comme: memset(array1, 10, 0)
pourrait être compilé pour un x86 comme quelque chose comme:
mov ecx, 10
xor eax, eax
mov edi, offset FLAT:array1
rep stosb
De telles intrinsèques sont purement une optimisation. "Besoin" d'intrinsèques serait très probablement une situation où le compilateur prend en charge des intrinsèques qui vous permettent de générer du code que le compilateur ne peut pas (ou ne veut généralement pas) générer directement. Pour un exemple évident, bon nombre de compilateurs pour x86 ont des "MMX Intrinsics" qui vous permettent d'utiliser des "fonctions" qui ne sont en réalité que des représentations directes des instructions MMX.
Une fonction intrinsèque est une fonction que le compilateur implémente directement lorsque cela est possible, plutôt que de se lier à une implémentation fournie par la bibliothèque de la fonction.
Un exemple courant est strncpy()
.
Pour les chaînes courtes, un appel de fonction à strncpy()
, qui implique la mise en place d'un "cadre de pile" avec une adresse de retour, prendra plus de temps que la copie réelle d'octets. Pire encore, l'effet sur les tampons de prélecture du processeur bloquera l'exécution du processeur pendant plusieurs cycles d'horloge.
Au lieu de cela, la fonction intrinsèque est implémentée par le compilateur au lieu d'un appel de fonction. Dans l'exemple de strncpy()
, le code de copie d'octets est émis directement à l'endroit où strncpy()
est appelé.
Semblable à cet exemple strncpy()
, chaque fonction intrinsèque est implémentée directement en tant que code en ligne si les contraintes requises sont respectées.
Une copie non intrinsèque de la fonction intrinsèque existe généralement toujours dans la bibliothèque standard, au cas où l'adresse de la fonction est nécessaire.
Par rapport aux fonctions en ligne, la fonction intrinsèque est fournie par le compilateur. Il n'y a pas de place dans le code source d'un programme C où la fonction intrinsèque est écrite, ni d'implémentation de bibliothèque qui doit être liée. Une fonction en ligne est différente en ce que le compilateur lit le code source de la fonction en ligne, mais elle est similaire en ce qu'elle peut ultérieurement émettre une traduction compilée de la fonction en ligne directement dans le code objet, en omettant la surcharge d'un appel de fonction.
En bref, la différence pratique entre une fonction intrinsèque et une fonction en ligne est que les fonctions intrinsèques sont "présentes" même si vous n'avez pas #include
le fichier d'en-tête nécessaire qui contient la déclaration de fonction. Pour une fonction en ligne, le fichier d'en-tête avec la déclaration de fonction doit être #include
'd (ou autrement déclaré) en premier.
Les intrinsèques sont exposées par le compilateur comme des fonctions qui ne font partie d'aucune bibliothèque, en soi.
Ceux que vous utiliseriez probablement le plus sont intrinsèques à l'assemblage qui sont traités par le compilateur comme étant précisément l'instruction machine qu'ils représentent. Vous les utiliseriez, par exemple, dans du code où vous devez tirer parti d'une instruction CPU spécifique que le compilateur ne génère pas automatiquement et où vous n'avez pas nécessairement besoin d'une section d'assemblage en ligne complète.
'' Intrinsics '' sont les caractéristiques d'un langage qu'un compilateur reconnaît et implémente sans que le programme ait besoin de les déclarer. Le compilateur peut, ou non, se lier à une bibliothèque d'exécution pour effectuer l'opération. En C++ par exemple, l'opération de copie de structure est implicite:
struct {
int a;
char b [100];
long c [27];
} s, t;
...
s = t; // this statement copies hundreds of bytes, likely with a rtl call
D'autres exemples incluent des langages comme Fortran où il existe un support implicite pour le type complexe, et les fonctions transcendantales (sinus, tangente, etc.) n'ont pas besoin - et ne peuvent pas - être déclarées. PHP, Javascript, Ruby, etc. ont des centaines de fonctions intrinsèques telles que créer et rechercher des tableaux, effectuer des correspondances d'expressions régulières, etc., etc.
Quant à vos autres questions, la seule différence est de savoir si elles doivent être déclarées. Par exemple, un programme C++ utilisant des fonctions transcendantales doit inclure des déclarations de bibliothèque mathématique:
#include <math.h>
Il n'y a pas de modèle particulier d'applications qui dépendent de l'intrinsèque; ce n'est qu'une question d'importance pour les rédacteurs et les programmeurs de compilateurs.