Ordinea operaţiilor

Operaţia asupra unui obiect în C se poate defini foarte simplu ca o modificare a obiectului sau a variabilei.
Limbajul C are integrat în interior un automat de determinare a ordinii operaţiilor. Acest automat (numit și state machine C) a fost conceput astfel încât să se evite situaţiile nedefinite. Pentru mai multe detalii vezi aici Order of operations
sau aici Precedence and Order of Evaluation(pentru pasionați :) ).

Punctul de succesiune este o stare abstractă a limbajului C care urmează să fie mapată într-o stare consistentă caracterizată prin valori concrete în regiştrii şi în memorie.

În general, ordinea de execuție a unui singur pas executat într-o singură instrucţiune nu este specificată. Dar limbajul C garantează că în momentul în care a ajuns la un punct de succesiune atunci valorile variabilelor sunt actualizate și în același timp corecte. Corecte din punct de vedere al procesării, dar nu neapărat corecte din punctul de vedere al programatorului care are impresia că operația scrisă de el este corectă (şi compilabilă) dar rezultatul este de cele mai multe ori nedefinit.

Puncte de succesiune
- Punctul în care se apelează o funcţie după ce se evaluează argumentele.
- După evaluarea operandului stâng pentru ŞI (AND,&&) logic sau operaţia SAU (||) logic.
- Sfârşitul operandului stâng al operatorului ?:
- După operandul stâng al operatorului virgula (,)
- După terminarea evaluării a întregii expresii:
- Evaluarea initializarii a unui obiect de tip auto
- O expresie urmată de punct şi virgulă ; (instrucţiune obişnuită ) - Toate expresiile din interiorul instructiunilor do, while, if, switch si for. - Expresia din instrucţiunea de return

Ordinea efectuării operațiilor în C este asigurata de automatul C, pentru că starea abstractă internă a automatului este garantat să fie sincronizată, dar nu neapărat bine definită. Starea internă a automatului C este aproape întotdeauna bine definită, dar exista anumite situații când nu se poate spune exact ce ar putea sa rezulte din o anumita operație.
O regulă de bază pentru a nu ajunge într-o stare nedefinită este să nu se modifice un obiect de două ori între două puncte de succesiune.
Am si niste exemple destul de sugestive:

#include "stdio.h"
int glob;
int value;
int i;
int a[20];

void f (void)
{
  glob = value + glob++;  /* undefined behaviour */
  printf("glob = %d",glob);
  glob = (glob++, glob) + /* undefined and
         (glob++, glob);   * unspecified behaviour */
  printf("glob = %d",glob);
  i = ++i + 1;            /* undefined */
  printf("i= %d",i);
  i = i + 1;              /* allowed */
  printf("i= %d",i);
  a[i++] = i;             /* undefined */
  printf("a[%d]= %d",++i,a[++i]);
  a[i] = i;               /* allowed */
  printf("i= %d",i);

}
int main(void)
{
 f();
 return 0;
}
Avem si o regula Misra foarte importantă:
- MISRA-C:2004, Rule 12.2(required): The value of an expression shall be the same under any order of evaluation.

Nu uitati , Keep It Simple !

Etichete

Afișați mai multe

Arhiva

Afișați mai multe