0
votes

Incrément variable par N Indice de tableau intérieur

Quelqu'un pourrait-il s'il vous plaît me dire si une telle construction est valide ou non (c'est-à-dire pas une UB) en C ++. J'ai des segfault à cause de cela et j'ai passé quelques jours à essayer de comprendre ce qui se passe là-bas.

Clang(3.8):  clang++ -O3 -S test.cpp

    leal    7(%rdi), %ebx
    movl    .L_ZZ4mainE5array+28(,%rax,4), %esi
    movl    $_ZSt4cout, %edi
    callq   _ZNSolsEi
    movl    $.L.str, %esi
    movl    $1, %edx
    movq    %rax, %rdi
    callq   _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l

GCC(5/7) g++-7 -O3 -S test.cpp

    leal    7(%rdi), %ebx
    movl    $_ZSt4cout, %edi
    subq    $16, %rsp
    .cfi_def_cfa_offset 32
    movq    %fs:40, %rax
    movq    %rax, 8(%rsp)
    xorl    %eax, %eax
    movabsq $425201762403, %rax
    movq    %rax, (%rsp)
    movslq  %ebx, %rax
    movl    (%rsp,%rax,4), %esi
    call    _ZNSolsEi
    movl    $.LC0, %esi
    movq    %rax, %rdi
    call    _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
    movl    %ebx, %esi


5 commentaires

Si vous posez une question à propos de C ++ et UB, ne marquez pas d'autres langues. C est une langue totalement différente avec d'autres règles sémantiques et d'autres points d'UB.


Quant à votre question, sauf si argc est -6 ou -7 alors vous utiliserez un indice hors limites et qui est bien sûr Ub. L'expression utilisée pour l'index doit être entièrement évaluée en premier et en C ++ toutes les variantes d'affectation sont des expressions simples.


Ma question est si un [i + = n] augmentera toujours i d'abord.


@DMitry oui bien sûr; Les problèmes ne se produisent que si vous utilisez ArgC ailleurs dans la même expression, car l'ordre de l'évaluation des sous-expressions dans une expression (et donc la propagation des effets secondaires) n'est généralement pas défini.


@DMitry avez-vous peut-être pensé à la sémantique de argc ++ ? Cette expression aurait la valeur d'origine, pré- comme un indice en argv; La nouvelle valeur ne serait visible que dans la prochaine déclaration. Mais l'expression argc + = 1 (ou + = 7 ) a la valeur de argc après l'incrément.


4 Réponses :


1
votes

C'est un comportement normal. Le nom du tableau est en fait un pointeur au premier élément de la matrice. Et le tableau [n] est identique à * (array + n)


0 commentaires

4
votes

En cas de A [i + = n] L'expression i + = n sera toujours évaluée avant d'accéder à l'index. Mais l'exemple que vous avez fourni invoque UB lorsque votre exemple de tableau contient seulement deux éléments et que vous accédez donc à des limites de la matrice.


3 commentaires

Fourni argc est inférieur à -7 ou supérieur à -6 (mais oui, c'est probablement le problème).


@ Petera.schneider argc ne devrait pas être négatif que si cela n'est modifié ailleurs à l'intérieur principal .


Vous avez un point - il est défini par l'exécution et je ne saurais pas de côté comment le rendre négatif à principal . Peut-être en fournissant des arguments de ligne de commande int_max + 7, mais je crains que la longueur de la ligne de commande ait lieu quelque part avant de cela.



4
votes

Par lui-même Array [argc + = 7] est OK, le résultat de argc + 7 sera utilisé comme index sur tableau .

Cependant, dans votre exemple tableau n'a que 2 éléments, et argc n'est jamais négatif, votre code entraînera donc toujours une UB en raison d'une limite hors limites. Accès au tableau.


0 commentaires

2
votes

Votre cas est clairement un comportement non défini, car vous dépasserez les limites de la matrice pour les raisons suivantes:

premier, expression array [argc + = 7] est égal à * ((tableau) + (argc + = 7)) et les valeurs des opérandes être évalué avant + est évalué (cf. ici ); Opérateur + = est une affectation (et non un effet secondaire), et la valeur d'une affectation est le résultat de argc (dans ce cas) après l'affectation (cf. ici ). Par conséquent, le + = 7 est efficace pour les sous-domestiques;

second, argc est défini en C ++ pour ne jamais négatif (cf. ici ); Donc, argc + = 7 sera toujours > = 7 (ou un débordement entier signé en scénariste très irréaliste, mais toujours ub alors).

Par conséquent, UB.


0 commentaires