7 votes

Bug MATLAB (ou comportement vraiment bizarre) avec les structures et les tableaux de cellules vides

Je n'ai aucune idée de ce qui se passe ici. J'utilise R2006b. Y a-t-il une chance que quelqu'un qui utilise une version plus récente puisse faire un test pour voir s'il obtient le même comportement, avant que je ne remplisse un rapport de bogue ?

code : ( bug1.m )

function bug1
S = struct('nothing',{},'something',{});
add_something(S, 'boing');          % does what I expect
add_something(S.something,'test');  % weird behavior
end

function add_something(X,str)
    disp('X=');
    disp(X);
    disp('str=');
    disp(str);
end

de la production :

>> bug1
X=
str=
boing
X=
test
str=
??? Input argument "str" is undefined.

Error in ==> bug1>add_something at 11
    disp(str);

Error in ==> bug1 at 4
add_something(S.something,'test');

Il semble que le vide et le néant de la S.something lui permet de déplacer les arguments d'un appel de fonction. Cela semble être un très mauvais comportement. A court terme, je veux trouver un moyen de contourner le problème (j'essaie de créer une fonction qui ajoute des éléments à un tableau de cellules initialement vide qui est membre d'une structure).

Edita:

Question corollaire : il n'y a donc aucun moyen de construire une struct contenant des tableaux de cellules vides ?

15voto

gnovice Points 70970

Comme vous l'avez déjà constaté vous-même, il ne s'agit pas d'un bogue mais d'une "fonctionnalité". En d'autres termes, il s'agit du comportement normal de l'application STRUCTURE fonction. Si vous transmettez à STRUCT des tableaux de cellules vides comme valeurs de champ, la fonction suppose que vous voulez un tableau de structure vide avec les noms de champ donnés.

>> s=struct('a',{},'b',{})

s = 

0x0 struct array with fields:
    a
    b

Pour transmettre un tableau de cellules vide en tant que valeur de champ réelle, vous devez procéder comme suit :

>> s = struct('a',{{}},'b',{{}})

s = 

    a: {}
    b: {}

Par ailleurs, tous Lorsque vous souhaitez définir la valeur d'un champ dans un tableau de cellules, l'utilisation de STRUCT exige que vous l'englobez dans un autre tableau de cellules. Par exemple, ceci crée un élément de structure unique dont les champs contiennent un tableau de cellules et un vecteur :

>> s = struct('strings',{{'hello','yes'}},'lengths',[5 3])

s = 

    strings: {'hello'  'yes'}
    lengths: [5 3]

Mais cela crée un tableau de deux éléments de structure, répartissant le tableau de cellules mais réplication le vecteur :

>> s = struct('strings',{'hello','yes'},'lengths',[5 3])

s = 

1x2 struct array with fields:
    strings
    lengths

>> s(1)

ans = 

    strings: 'hello'
    lengths: [5 3]

>> s(2)

ans = 

    strings: 'yes'
    lengths: [5 3]

2voto

Jason S Points 58434

ARGH... Je crois que j'ai trouvé la réponse. struct() a de multiples comportements, notamment

Note Si l'un des champs de valeurs est un tableau de cellules vides {}, le logiciel MATLAB [ ] vide dans lequel tous les champs sont également vides.

et apparemment si vous passez un membre d'une structure 0x0 comme argument, c'est comme une sorte de fantôme vide qui n'apparaît pas vraiment dans la liste des arguments. (c'est encore probablement un bug)

bug2.m :

function bug2(arg1, arg2)
disp(sprintf('number of arguments = %d\narg1 = ', nargin));
disp(arg1);

cas de test :

>> nothing = struct('something',{})

nothing = 

0x0 struct array with fields:
    something

>> bug2(nothing,'there')
number of arguments = 2
arg1 = 
>> bug2(nothing.something,'there')
number of arguments = 1
arg1 = 
there

2voto

Ofek Shilon Points 3170

Ce comportement persiste dans 2008b, et n'est en fait pas vraiment un bogue (même si je ne dirais pas que les concepteurs l'ont voulu) : Lorsque vous entrez dans add_something(S, 'boing') et que vous observez le premier argument (par exemple en le sélectionnant et en appuyant sur F9), vous obtenez certains sortie relative à la structure vide S. Entrez dans add_something(S.something,'test') et observez le premier argument, et vous verrez qu'il est en fait interprété comme 'test' !

La syntaxe struct.fieldname est conçue pour renvoyer un objet de type "liste séparée par des virgules". Les fonctions de Matlab sont conçues pour recevoir un objet de ce type exact : les noms des arguments sont donnés aux valeurs de la liste, dans l'ordre où elles sont transmises. Dans votre cas, puisque le premier argument est un liste vide la liste séparée par des virgules que reçoit la fonction commence réellement à la deuxième valeur que vous transmettez, à savoir "test".

1voto

Ben Schwehn Points 3162

La sortie est identique dans R2008b :

>> bug1
X=
str=
boing
X=
test
str=
??? Input argument "str" is undefined.

Error in ==> bug1>add_something at 11
    disp(str);

Error in ==> bug1 at 4
add_something(S.something,'test');  % weird behavior

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X