Appel de procédures et de fonctions (Delphi)

De RAD Studio
Aller à : navigation, rechercher

Remonter à Procédures et fonctions - Index

Cette rubrique traite les sujets suivants :

  • Contrôle des programmes et paramètres des routines
  • Constructeurs de tableaux ouverts
  • Directive inline

Contrôle des programmes et paramètres

Quand vous appelez une procédure ou une fonction, le contrôle du programme passe du point d'appel au corps de la routine. Vous pouvez faire l'appel en utilisant le nom déclaré de la routine (avec ou sans qualificateur) ou en utilisant une variable procédure pointant sur la routine. Dans les deux cas, si la routine est déclarée avec des paramètres, votre appel doit transmettre des paramètres qui correspondent en ordre et en type à ceux spécifiés dans la liste des paramètres de la routine. Les paramètres transmis à la routine sont appelés paramètres réels alors que les paramètres de déclaration de la routine sont appelés paramètres formels.

Dans l'appel d'une routine, n'oubliez pas que :

  • Les expressions utilisées pour transmettre des paramètres const typés et des paramètres valeur doivent être compatibles pour l'affectation avec les paramètres formels correspondants.
  • Les expressions utilisées pour transmettre des paramètres var et out doivent être de même type que les paramètres formels correspondants, sauf si le paramètre formel est sans type.
  • Seules des expressions pouvant apparaître à gauche d'une affectation peuvent s'utiliser pour transmettre des paramètres var et out.
  • Si les paramètres formels d'une routine sont sans type, les nombres et les constantes vraies avec des valeurs numériques ne peuvent pas être utilisés en tant que paramètres réels.

Quand vous appelez une routine qui utilise des valeurs de paramètre par défaut, tous les paramètres réels suivant le premier pour lequel vous utilisez la valeur par défaut doivent également utiliser leur valeur par défaut. Ainsi un appel de la forme SomeFunction(,,X) est incorrect.

Vous pouvez omettre les parenthèses lors de la transmission de tous les paramètres par défaut, et seulement des paramètres par défaut, à une routine. Par exemple, avec la procédure suivante

procedure DoSomething(X: Real = 1.0; I: Integer = 0; S: string = '');

les appels suivants sont équivalents.

DoSomething();
DoSomething;

Constructeurs de tableaux ouverts

Les constructeurs de tableaux ouverts permettent de construire directement des tableaux dans l'appel de la procédure ou de la fonction. Ils ne peuvent être transmis que comme paramètres tableau ouvert ou comme paramètres tableau ouvert variant.

Un constructeur de tableau ouvert, comme un constructeur d'ensemble, est une série, placée entre crochets, d'expressions séparées par des virgules.

Par exemple, soit ces déclarations :

var I, J: Integer;
procedure Add(A: array of Integer);

vous pouvez appeler la procédure Add avec l'instruction :

Add([5, 7, I, I + J]);

C'est équivalent à

var Temp: array[0..3] of Integer;
  // …
  Temp[0] := 5;
  Temp[1] := 7;
  Temp[2] := I;
  Temp[3] := I + J;
  Add(Temp);

Les constructeurs de tableau ouvert ne peuvent être transmis qu'à des paramètres valeur ou const. Les expressions du constructeur doivent être compatibles pour l'affectation avec le type de base du paramètre tableau. Dans le cas d'un paramètre tableau ouvert variant, les expressions peuvent être de types différents.

Utilisation de la directive inline

Pour améliorer les performances, le compilateur Delphi permet le balisage des fonctions et procédures à l'aide de la directive inline. Si une fonction ou procédure répond à certains critères, le compilateur insère directement le code au lieu de générer un appel. L'utilisation de cette directive induit une optimisation des performances pouvant se traduire par un code plus rapide, mais elle présente des inconvénients en termes d'espace. En effet, elle entraîne toujours la création d'un fichier binaire plus volumineux par le compilateur. Comme les autres directives, la directive inline est utilisée dans les déclarations et définitions de fonctions et de procédures.

procedure MyProc(x:Integer); inline;
begin
    // …
end;

function MyFunc(y:Char) : String; inline;
begin
  // …
end;

L'utilisation de la directive inline par le compilateur n'est qu'une suggestion. En effet, il n'existe aucune garantie quant à son utilisation par le compilateur pour une routine particulière car, dans certains cas, cette directive ne peut pas être employée. La liste suivante décrit les situations dans lesquelles la directive inline peut ou ne peut pas être utilisée :

  • Elle n'est pas utilisée sur les méthodes liées en différé (méthodes virtuelles, dynamiques, de message).
  • Elle n'est pas utilisée sur les routines contenant du code assembleur.
  • Elle n'est pas utilisée sur les constructeurs et destructeurs.
  • Elle ne peut pas être utilisée sur le bloc de programme principal, ni sur les blocs d'initialisation et de finalisation d'une unité.
  • Les routines qui ne sont pas définies avant l'utilisation ne peuvent pas être utilisées.
  • Elle ne peut pas être utilisée sur les routines qui prennent des paramètres tableau ouvert.
  • Elle peut être utilisée sur du code se trouvant dans des packages, mais jamais sur les limites des packages.
  • Elle n'est pas utilisée sur les unités circulairement dépendantes, y compris les dépendances circulaires indirectes. Prenons l'exemple de l'unité A qui utilise l'unité B, cette dernière utilisant l'unité C qui, à son tour, utilise l'unité A. Dans cet exemple, lors de la compilation de l'unité A, le code de l'unité B ou de l'unité C ne pourra pas être balisé avec la directive inline dans l'unité A.
  • Pour que le compilateur puisse baliser avec la directive inline le code d'une unité qui se trouve dans une dépendance circulaire, le code à baliser doit provenir d'une unité située à l'extérieur de la relation circulaire. Dans l'exemple ci-dessus, si l'unité A utilise également l'unité D, le code de l'unité D peut être balisé avec inline dans A, car l'unité D n'est pas impliquée dans la dépendance circulaire.
  • Si une routine est définie dans la section interface et si elle accède à des symboles définis dans la section implementation, cette routine ne peut pas être balisée avec la directive inline.
  • Si une routine marquée avec inline utilise des symboles externes provenant d'autres unités, toutes ces unités doivent être répertoriées dans l'instruction uses ; sinon, la routine ne peut pas être balisée avec inline.
  • Dans une unité, le corps d'une fonction en ligne doit être défini avant les appels de la fonction. Sinon, le corps de la fonction, qui n'est pas connu du compilateur lorsqu'il atteint le site de l'appel, ne pourra pas être développé en ligne.

Si vous modifiez l'implémentation d'une routine marquée avec inline, toutes les unités qui utilisent cette fonction seront recompilées. Cela diffère des règles de reconstruction traditionnelles, qui impliquaient que les reconstructions n'étaient déclenchées que par des modifications apportées à la section interface d'une unité.

La directive {$INLINE} du compilateur vous permet de mieux contrôler le balisage avec inline. Vous pouvez utiliser la directive {$INLINE} à l'emplacement de la définition de la routine marquée avec inline, ainsi que sur le lieu de l'appel. Voici les valeurs possibles et leur signification :

Valeur Signification sur la définition Signification sur le lieu de l'appel

{$INLINE ON} (par défaut)

Si elle est balisée avec la directive inline, la routine est compilée comme un élément pouvant être marqué avec inline.

La routine sera développée en ligne si cela est possible.

{$INLINE AUTO}

Se comporte comme {$INLINE ON}, mais les routines non marquées avec inline seront balisées avec inline si la taille de leur code est inférieure ou égale à 32

{$INLINE AUTO} est sans effet sur le fait qu'une routine sera en ligne lorsqu'elle est utilisée sur le site d'appel de la routine.

{$INLINE OFF}

La routine ne sera pas marquée comme pouvant être inline, même si elle est balisée avec inline.

La routine ne sera pas développée en ligne.

Voir aussi