cosa succede se metto = al posto di == nelle condizioni di un if?

il titolo è autoesplicativo.
stavo creando un codice di debounce e non funzionava, poi mi sono reso conto che quello era il problema.

cosa succedeva dentro al micro?
faceva assumere valori uguali alle varibili?

Semplicemente viene trattato come un'assegnazione, di cui viene poi testato il "valore di ritorno", ovvero il valore assegnato.

In pratica:

if (a = 0) {
  // Ora a vale 0 e qua dentro non si entrerà mai
}

if (a = 5) {
  // Ora a vale 5 ed entriamo qua dentro
}

capisco, quindi è molto sbagliato usarlo in un if

Non necessariamente, ma bisogna sapere cosa si sta facendo :-*. Ad esempio, io scrivo spesso in C:

if ((fp = fopen ("/qualche/file", "r"))) {
  /* ... */
}

Un assegnazione ritorna sempre con TRUE percui il IF é sempre vero.
Ciao Uwe

uwefed:
Un assegnazione ritorna sempre con TRUE percui il IF é sempre vero.

Mi spiace ma ti sbagli. Dallo standard C99, sezione 6.5.16:

An assignment expression has the value of the left operand after the assignment

(Vedi c - What does an assignment return? - Stack Overflow)

Allora ritorna (quasi) sempre TRUE eccetto se faccio per esempio a=0 ?

Ciao Uwe

Si @uwe.
Infatti spesso si usa questo test postato da @sukko

if ( fp = fopen("/qualche/file", "r") ) {
  // okay file opened, fp != 0
}

che sarebbe

fp = fopen("/qualche/file", "r");
if ( fp ) {  
  // okay file opened, fp != 0
}

Posso dire che potevano usare un'altro simbolo al posto di "=="?

Proprio oggi ho fatto questo errore che è difficile da trovare in listati lunghi.

E pensa che in php c'è pure === :grin:.

In realtà è solo questione di abitudine, dopo un po' ci si fa l'occhio, ma nemmeno si sbaglia più.

@uwefed:
Un assegnazione ritorna sempre con TRUE percui il IF é sempre vero.

Assolutamente "False", l'assegnazione ritorna il valore dell'assegnazione stessa quando ben formattata, essa, riallacciandomi a

@cyberhs:
Proprio oggi ho fatto questo errore che è difficile da trovare in listati lunghi

Viene identificata immediatamente da UN BUON COMPILATORE emettendo un ERRORE quando non trova un operatore '=' (assegnazione) al di fuori delle parentesi tonde, già dal c'89.
Tale tecnica amata dai puristi C è assolutamente DEPRECATA!
Nel C lo 0 assume molteplici forme, dalla fine di un vettore di caratteri passando ai NULL pointer alle funzioni che non ritornano errori e pertantanto consentono di sintetizzare il codice in una singola linea.

Pertanto io consiglio di usare la modalità estesa anche se alla fine finisco sempre ad usare moltiplici linee di codice al limite dell'obfuscated code.

vbextreme:
Assolutamente "False", l'assegnazione ritorna il valore dell'assegnazione stessa ...

Sei troppo tardi. Hanno giá segnalato ed ho riformulato la frase.
Ciao Uwe

vbextreme:
Viene identificata immediatamente da UN BUON COMPILATORE emettendo un ERRORE quando non trova un operatore '=' (assegnazione) al di fuori delle parentesi tonde, già dal c'89.
Tale tecnica amata dai puristi C è assolutamente DEPRECATA!

GCC emette un warning:

warning: suggest parentheses around assignment used as truth value
This warning highlights a potentially serious error, using the assignment operator '=' instead of the comparison operator '==' in the test of a conditional statement or other logical expression. While the assignment operator can be used as part of a logical value, this is rarely the intended behavior. Example:
#include <stdio.h>

int
main (void)
{
int i = 0;
if (i = 1) { /* = should be == */
printf ("unexpected result\n");
}
return 0;
}
The test above should be written as if (i == 1), otherwise the variable i will be set to 1 by the evaluation of the if statement itself. The operator '=' both assigns and returns the value of its right-hand side, causing the variable i to be modified and the unexpected branch taken. Similar unexpected results occur with if (i = 0) instead of if (i == 0), except that in this case the body of the if statement would never be executed. This warning is suppressed if the assignment is enclosed in additional parentheses to indicate that it is being used legitimately.

Comunque non mi pare che sia una tecnica strettamente deprecata. Sicuramente non è il massimo della leggibilità, ma a volte permette di evitare di replicare linee di codice.

Se non ricordo male è anche DEPRECATA nel MISRA, dovrei tornare a leggerlo.
È una cattiva tecnica di programmazione che può portare ad errori difficili da trovare sopratutto quando vengono eseguite più operazioni all'interno dell'if, questo causa l'inserimento di parentesi tonde eludendo così i controlli del compilatore.

p.s. per me i warning sono errori, non deve essercene nemmeno uno.

Beh, il fatto che sia deprecato nel MISRA non vuol dire che sia deprecato in assoluto, ma concordo comunque che sia una tecnica che va centellinata.

Sui warning concordo pienamente! :slight_smile:

Il MISRA è la bibbia dei microcontrollori embededd!
Magari la seguissero tutti, almeno smetteremmo di vedere delle malloc().....

Molte regole(se non tutte) sono valide anche sui mainstream.

Naturalmente sui warning ho un pò estremizzato, capita che su lunghi brani e con tutti i flags accesi qualche d'uno rimanga....

vbextreme:
Se non ricordo male è anche DEPRECATA nel MISRA, dovrei tornare a leggerlo.

MISRA C-2012 - Rule 14.4
The controlling expression of an if statement and the controlling expression of an iteration-statement shall have essentially Boolean type.

Category: Required

... credo che tu ti riferisca a questa regola :wink:

Guglielmo

si ma dovrebbe esserci qualcosa a riguardo anche sul metodo di scrittura del codice, ovvero che bisogna scrivere il codice in modalità "lunga" e non "compatta".
Sono in vacanza e non ho il MISRA a portata di mano......

... mmm probabilmente, e c'è anche il caso specifico in questione, la regola che meglio si adatta è la 13.4 :wink: :

Rule 13.4
The result of an assignment operator should not be used

/*

  • Non-compliant - value of bool_var = false is used but
  • bool_var == false was probably intended
    */
    if ( bool_var = false )
    {
    }

Guglielmo