Contenu principal

La traduction de cette page n'est pas à jour. Cliquez ici pour voir la dernière version en anglais.

Résoudre le problème : les variables doivent être entièrement définies avant utilisation

Problème

Contrairement à MATLAB® qui est un langage à typage dynamique, le C et le C++ ont un typage statique. Cela signifie que le générateur de code doit être en mesure de déterminer le type de toutes les variables de votre code MATLAB pour définir et allouer des variables dans le code généré. Si le générateur de code ne parvient pas à déterminer le type d’une ou plusieurs variables dans votre code MATLAB, il renvoie un message d’erreur contenant la phrase suivante :

For code generation, all variables must be fully defined before use.

Si le message d’erreur affiché concerne un cell array ou un élément de cell array, consultez Resolve Issue: Cell Array Elements Must Be Fully Defined Before Use.

Solutions possibles

Pour résoudre ce problème, affectez des valeurs à toutes les variables de votre code MATLAB sur tous les chemins d’exécution. Cela comprend toutes les variables figurant dans d’autres structures de données telles que les champs de structure et les propriétés de classe. Essayez l’une des solutions suivantes en fonction de votre code MATLAB et du message d’erreur spécifique qui s’affiche.

Affecter des valeurs aux variables sur tous les chemins d’exécution

Dans certains cas, le générateur de code ne parvient pas à déterminer que toutes les variables sont définies sur tous les chemins d’exécution. Par exemple, créez une fonction MATLAB undefinedVariableTest qui reçoit une entrée numérique x et renvoie la valeur absolue de x.

function y = undefinedVariableTest(x) %#codegen
arguments
    x (1,1) double
end
if x == 0
    y = 0;
elseif x < 0
    y = -x;
elseif x > 0
    y = x;
end
end
Pendant l’exécution dans MATLAB, les appels de undefinedVariableTest renvoient une valeur pour toutes les valeurs de x. Toutefois, la génération de code échoue pour undefinedVariableTest, car le générateur de code ne trouve pas d’instruction else et ne peut donc pas déterminer que y est défini sur tous les chemins d’exécution possibles.

Pour que ce code convienne pour la génération de code, obligez le générateur de code à détecter que y est défini sur tous les chemins d’exécution possibles en utilisant une instruction else.

function y = undefinedVariableTest(x) %#codegen
arguments
    x (1,1) double
end
if x == 0
    y = 0;
elseif x < 0
    y = -x;
else
    y = x;
end
end

Une autre solution consiste à affecter une valeur fictive à y en dehors de l’instruction if.

function y = undefinedVariableTest(x) %#codegen
arguments
    x (1,1) double
end
y = 0;
if x == 0
    y = 0;
elseif x < 0
    y = -x;
elseif x > 0
    y = x;
end
end

Affecter des valeurs à tous les champs de structure et propriétés de classe

Vous devez définir toutes les variables contenues dans d’autres types de données sur tous les chemins d’exécution. Vous ne pouvez pas modifier le nombre ni le format des champs de structure ou des propriétés de classe une fois que la structure ou la classe a été utilisée. En outre, pour certains patterns de codage, le générateur de code n’est pas en mesure de détecter que toutes les variables contenues dans un autre type de données sont définies. Dans ces situations, essayez de réécrire votre code avec un pattern de codage différent.

Champs de structure. Dans le code MATLAB destiné à la génération de code, vous ne pouvez pas ajouter de champs à une structure une fois que vous l’avez lue, indexée ou passée à une fonction. Par exemple, créez une fonction MATLAB undefinedFieldTest qui renvoie une structure y. Si x est supérieur à 10, undefinedFieldTest définit et affecte une valeur au champ field1 de la structure s. Sinon, undefinedFieldTest définit et affecte des valeurs aux champs field1 et field2 de la structure s.

function y = undefinedFieldTest(x) %#codegen
arguments
    x (1,1) double
end
if x > 10
    s.field1 = 11;
else
    s.field1 = 12;
    s.field2 = 12;
end
y = s;
end
Pendant l’exécution dans MATLAB, le champ field2 est ajouté de manière dynamique à la structure s si x est inférieur ou égal à 10. Cependant, le générateur de code doit déterminer le type de tous les champs contenus dans la structure s au moment de la génération du code alors que la valeur run-time de x est inconnue. La génération de code échoue, car le générateur de code détecte que le champ field2 fait partie de la structure s sur certains chemins d’exécution mais pas sur d’autres.

Pour que ce code convienne pour la génération de code, ne modifiez pas le nombre ni le nom des champs contenus dans une structure au run-time. Définissez tous les champs de s indépendamment de la valeur run-time de x.

function y = undefinedFieldTest(x) %#codegen
arguments
    x (1,1) double
end
s = struct("field1", [], "field2", []);
if x > 10
    s.field1 = 11;
else
    s.field1 = 12;
    s.field2 = 12;
end
y = s;
end
Pour en savoir plus sur l’utilisation de types de données de structure dans le code MATLAB pour la génération de code, consultez Définition de structures pour la génération de code.

Propriétés de classe. Pour certains patterns de codage où vous affectez des valeurs à des propriétés de classe dans une boucle, le générateur de code n’est pas en mesure de détecter que toutes les propriétés sont définies. Par exemple, créez une fonction MATLAB undefinedPropTest qui reçoit un entier positif n en entrée et renvoie une instance de la classe MyClass. La classe MyClass a deux propriétés prop1 et prop2. La fonction undefinedPropTest affecte des valeurs à prop1 et prop2 pour l’objet myClass renvoyé dans une boucle for.

function y = undefinedPropTest(n) %#codegen
arguments
    n (1,1) double {mustBePositive, mustBeInteger}
end
x = MyClass;
for i = 1:n
    x.prop1 = 1 + i;
    x.prop2 = x.prop1 + 3;
end
y = x;
end
Pendant l’exécution dans MATLAB, undefinedPropTest renvoie une instance de MyClass pour toutes les valeurs autorisées de n. Toutefois, la génération de code pour undefinedPropTest échoue, car le générateur de code ne peut pas déterminer que undefinedPropTest affecte des valeurs à prop1 et prop2 pour toutes les valeurs de n.

Pour que ce code convienne pour la génération de code, affectez des valeurs fictives à toutes les propriétés de MyClass avant la boucle for.

function y = undefinedPropTest(n) %#codegen
arguments
    n (1,1) double {mustBePositive, mustBeInteger}
end
x = MyClass;
x.prop1 = 0;
x.prop2 = 0;
for i = 1:n
    x.prop1 = 1 + i;
    x.prop2 = x.prop1 + 3;
end
y = x;
end
Pour connaître les autres points à prendre en compte lors de la définition de propriétés de classe dans le code MATLAB pour la génération de code, consultez Define Class Properties for Code Generation.

Affecter des valeurs initiales à toutes les variables persistantes

Vous devez définir toutes les variables persistent de votre code MATLAB sur tous les chemins d’exécution. Par exemple, créez une fonction MATLAB undefinedPersistentTest qui stocke le nombre de fois où elle a été appelée dans la variable persistent nommée count. Pour initialiser ou réinitialiser count, undefinedPersistentTest doit être appelée avec l’argument 0.

function y = undefinedPersistentTest(x)
persistent count;
if x == 0
    count = 0;
else
    count = count + 1;
end
y = count;
end

MATLAB définit automatiquement une variable persistante égale à une matrice vide ([]) à la première occurrence. Par conséquent, les appels de undefinedPersistentTest ne produisent aucune erreur même si une valeur a été affectée à count. Toutefois, le générateur de code ne peut pas déterminer la taille et le type d’une variable persistante non initialisée au moment de la génération du code. Par conséquent, la génération de code pour undefinedPersistentTest échoue, car count n’est pas défini pour toutes les valeurs de x.

Pour que ce code convienne pour la génération de code, utilisez la fonction isempty pour affecter une valeur à count si cette variable n’est pas définie.

function y = undefinedPersistentTest(x)
arguments
    x (1,1) double
end
persistent count;
if isempty(count)
    count = 0;
end
if x == 0
    count = 0;
else
    count = count + 1;
end
y = count;
end

Définir les variables sans affectation

Dans certaines situations, la définition des variables par affectation dans le code généré représente une surcharge importante. Elle peut également entraîner l’apparition de copies redondantes des variables dans le code généré. Pour définir le type, la taille et la complexité des variables sans la surcharge associée à leur affectation, utilisez coder.nullcopy.

L’utilisation de coder.nullcopy pour définir une variable vous permet de générer le code sans avoir à respecter les patterns de codage décrits ci-dessus. Prenons l’exemple de la fonction nullcopyExample. Comme elle utilise coder.nullcopy pour préallouer de la mémoire pour la classe MyClass, vous n’avez pas besoin d’affecter des valeurs fictives aux propriétés de cette classe.

function y = nullcopyExample(n) %#codegen
arguments
    n (1,1) double {mustBePositive, mustBeInteger}
end
x = coder.nullcopy(MyClass);
for i = 1:n
    x.prop1 = 1 + i;
    x.prop2 = x.prop1 + 3;
end
y = x;
end

Remarque

Utilisez coder.nullcopy avec prudence. Veillez à affecter des valeurs à toutes les variables, y compris les propriétés de classe, les champs de structure et les éléments de tableau. L’accès à des variables non initialisées peut produire des résultats imprévisibles.

Voir aussi

|

Rubriques