Contenu principal

Bonnes pratiques pour définir les variables pour la génération de code C/C++

Le code MATLAB® utilisé pour la génération de code doit respecter certaines restrictions. Lorsque vous définissez des variables, suivez ces bonnes pratiques pour optimiser leur utilisation et éviter de générer des erreurs dans votre code.

Définir les variables de manière explicite avant de les utiliser

Pour générer du code C/C++, vous devez définir les valeurs et les propriétés des variables de manière explicite avant de les utiliser dans des opérations ou de les renvoyer en sortie. Vous évitez ainsi les erreurs qui se produisent lorsque vous ne définissez pas la variable.

Remarque

Lorsque vous définissez des variables, elles sont locales par défaut et ne sont pas conservées d’un appel de fonction à un autre. Pour rendre les variables persistantes, utilisez la fonction persistent.

L’initialisation d’une nouvelle variable en crée parfois des copies redondantes dans le code généré. Pour plus d’informations, consultez Eliminate Redundant Copies of Variables in Generated Code.

Définir les variables sur tous les chemins d’exécution

Vous devez définir une variable sur tous les chemins d’exécution, notamment ceux créés par les instructions if. Prenons l’exemple de ce code MATLAB qui définit une variable avant de l’utiliser comme entrée d’une fonction :

...
if c <= 0
  x = 11;
end
% Later in your code ...
if c > 0
% Use x in the function foo
  foo(x);
end
...
Le code affecte une valeur à x seulement si c <= 0 mais utilise x seulement quand c > 0. Selon la valeur de c, ce code peut fonctionner dans MATLAB sans erreur. Toutefois, la génération de code échoue quand vous essayez de générer du code C/C++ à partir de ce code MATLAB, car le générateur de code détecte que x n’est pas défini sur le chemin d’exécution quand c > 0.

Pour que ce code convienne pour la génération de code, définissez x avant de l’utiliser :

x = 0;
...
if c <= 0
  x = 11;
end
% Later in your code ...
if c > 0
% Use x in the function foo
  foo(x);
end
...

Définir tous les champs de structure

Vous devez également définir chaque champ de structure pour tous les chemins d’exécution. Prenons l’exemple de ce code MATLAB :

...
if c > 0 
  s.a = 11;
  disp(s);
else
  s.a = 12;
  s.b = 12;
end
% Use s in the function foo
foo(s);
...
La première partie de l’instruction if utilise uniquement le champ a alors que l’instruction else utilise les champs a et b. Ce code fonctionne dans MATLAB mais entraîne une erreur de compilation pendant la génération de code C/C++. Pour éviter cette erreur, n’ajoutez pas de champs à une structure après l’avoir utilisée. Pour plus d’informations, consultez Définition de structures pour la génération de code.

Pour que ce code convienne pour la génération de code C/C++, définissez les champs de s avant de les utiliser :

...
% Define fields in structure s
s = struct("a", 0, "b", 0);
if c > 0 
  s.a = 11;
  disp(s);
else
  s.a = 12;
  s.b = 12;
end
% Use s in the function foo
foo(s);
...

Réaffecter les propriétés des variables avec prudence

Il est possible de réaffecter certaines variables avec une valeur de classe, de taille ou de complexité différente après l’affectation initiale. Consultez la rubrique Reassignment of Variable Properties (MATLAB Coder). Toutefois, si vous réaffectez le type de la variable après l’affectation initiale, le code renvoie souvent une erreur de compilation pendant la génération de code. En règle générale, mieux vaut affecter une classe, une taille, un type et une complexité spécifiques à chaque variable.

Définir des types de données numériques pour les variables

double est le type de données numériques par défaut dans MATLAB. Pour définir des variables avec d’autres types de données, vous devez spécifier le type de manière explicite avec le préfixe ou l’opérateur adéquat dans la définition. Faites attention aux types de données que vous choisissez, car l’utilisation de variables affectées à des types de données différents peut entraîner des erreurs de non-concordance de type.

Par exemple, le code suivant définit la variable x en tant que double et y en tant qu’entier 8 bits :

x = 15;
y = uint8(x);

Pour plus d’informations sur les types supportés dans MATLAB, consultez Types numériques.

Définir les matrices avant d’affecter des variables indexées

Le fait d’agrandir une variable en écrivant un élément dépassant sa taille actuelle entraîne une erreur de compilation ou de run-time, sauf si vous utilisez l’indexation « end + 1 » ou définissez d’abord la variable comme étant de taille variable. Consultez Generate Code for Growing Arrays and Cell Arrays with end + 1 Indexing (MATLAB Coder) et Define Variable-Size Data for Code Generation. Pour éviter les erreurs liées à la taille sans utiliser l’indexation « end + 1 » ni définir des tableaux de taille variable, définissez la taille maximale du tableau avant d’affecter des valeurs à ses éléments.

Par exemple, l’affectation suivante entraîne une erreur au moment de la génération du code :

g = zeros(3,3);
g(5,2) = 14.6;

Corrigez ce code en définissant une matrice g de taille suffisante :

g = zeros(5,5);
g(5,2) = 14.6;

Pour plus d’informations sur l’indexation des matrices, consultez Incompatibility with MATLAB in Matrix Indexing Operations for Code Generation.

Essayer d’indexer les tableaux avec des vecteurs de taille fixe

Bien que la génération de code supporte les tableaux de taille variable, ceux-ci nécessitent davantage de mémoire, ce qui peut causer des lenteurs. Si possible, utilisez des vecteurs de valeurs constantes pour indexer les tableaux. Par exemple :

...
% extract 7 elements from A using a constant-value vector
B = A(1:7);
...
Dans cet exemple, le générateur de code détecte que B est de taille fixe.

Si vous indexez un tableau avec l’opérateur colon et des valeurs de variables, le générateur de code ne détermine pas toujours correctement si le tableau est de taille fixe ou variable. Par exemple, les deux tableaux suivants sont tous les deux de taille fixe, quelle que soit la valeur de i :

...
% extract 7 elements from A using a fixed-size vector
B = A(i-1:i+5);
C = A(-1+2*i:5+2*i);
...
Lorsque la valeur de i est connue au moment de la génération du code, le générateur de code détecte que B et C sont des tableaux de taille fixe. En revanche, lorsque la valeur de i est inconnue au moment de la génération du code, le générateur de code détecte que B est de taille fixe mais il définit C comme étant de taille variable. En conséquence, vous pouvez essayer de définir un tableau qui ne change pas de taille et devrait donc être de taille fixe, mais le générateur de code l’interprète et le spécifie comme étant de taille variable.

Dans un tel cas, vous pouvez réécrire votre code MATLAB pour obliger le générateur de code à détecter que le tableau défini ne change pas de taille. Par exemple, vous pouvez réécrire la définition de C ci-dessus pour extraire l’expression d’indexation du tableau à partir des opérations mathématiques utilisant la variable (i) qui est inconnue au moment de la génération du code :

...
% extract 7 elements from A using a fixed-size vector
C = A(2*i+(-1:5));
...
Après cette réécriture, le générateur de code détecte que C est un tableau de taille fixe.

Dans d’autres patterns de code, les indices du tableau comprennent des variables qui influent sur sa taille mais qui sont connues au moment de la compilation. Dans ce cas, le tableau extrait est en fait de taille fixe mais il se peut que le générateur de code ne l’identifie pas comme tel et le traite comme étant de taille variable. Vous pouvez éventuellement réécrire un tel code pour générer des tableaux de taille fixe. Dans l’exemple suivant, les tableaux D_varSize et D_fixSize sont identiques. Cependant, le générateur de code définit D_varSize comme étant de taille variable et D_fixSize de taille fixe :

...
width = 25;              
D_varSize = A(i-width:i+width);  % D_varSize is variable-size if i is unknown at compile time 
D_fixSize = A(i+(-width:width)); % D_fixSize is fixed-size whether or not i is unknown at compile time
...

Voir aussi

| |

Rubriques