Go Down

Topic: #define e const byte e le loro reali differenze (Read 1 time) previous topic - next topic

miky_police

Altra stupida domanda, tanto quanta quella posta sullo switch...

Code: [Select]

#define mioLed 1
const byte mioLed = 2;


Quale usereste delle due, ma soprattutto per quale motivo (memoria RAM, prestazioni, correttezza di definizione secondo voi o secondo il compilatore)...

NOTA: pongo queste domande perché a volte usiamo entrambi le modalità di definire i pin, ma alcuni (proprio come me) non sanno quello che effettivamente varia all'interno del compilatore nonché dell'mcu... Se fossero uguali non avrebbe senso avere due modi di scrivere diversi... Quindi, qualcuno di buon animo, sarebbe disposto a scambiare due chiacchiere? OT: prevedo già qualcuno che mi indica dove devo andare a leggere... :D :D
Il vero stupido è colui che fa e rifa la stessa cosa aspettandosi risultati diversi. A.E.

gpb01

#1
Feb 07, 2019, 01:37 pm Last Edit: Feb 07, 2019, 01:45 pm by gpb01
Altra stupida domanda, tanto quanta quella posta sullo switch...
... e niente eh, non c'è nulla da fare, quando uno è pigro è pigro ! :smiley-evil: :smiley-evil: :smiley-evil:

E' cosa di cui si è parlato tante volte sul forum e basta fare una piccola ricerca per trovare vecchie discussioni, come QUESTA. Alla fine del thread, la risposta di Astrobeed, è esauriente.

Guglielmo

P.S.: In fondo a tutti i mei post, lo vedi il testo in "firma" ?  :smiley-twist:
Search is Your friend ... or I am Your enemy !

miky_police

ok... ricevuto... se solo potessi usare quel report to moderator :D :D :D
Come al solito GRAZIE...

Ovviamente chiunque avesse qualcosa da aggiungere al riguardo (magari con esempi banali), seguo il post con interesse...

Grazie ancora gpb01.
Il vero stupido è colui che fa e rifa la stessa cosa aspettandosi risultati diversi. A.E.

Silente

#3
Feb 07, 2019, 03:19 pm Last Edit: Feb 07, 2019, 03:20 pm by Silente
Se ho capito bene per singole variabili sono uguali. Solo che #define é un "cerca e sostituisci", quindi non crea la variabile (può anche essere usato per creare finte funzioni o accorciare pezzi fi codice ripetuti) mentre const la crea, e per questo puoi farne array, se fosse più comodo. Personalmente const po uso solo in caso di array, per singole variabili uso #define

Chiaramente quando dico " variabili" intendo non modificabili
Dove va un numero va una variabile, una funzione e/o  un test.
Per ottenere devi spiegare

Strumenti/Formattazione automatica fino alla morte!
Cristianesimo:bibbia='C':K&R

gpb01

#4
Feb 07, 2019, 03:23 pm Last Edit: Feb 07, 2019, 03:23 pm by gpb01
Chiaramente quando dico " variabili" intendo non modificabili
... e allora usa il termine giusto ... costanti:smiley-evil:

Guglielmo
Search is Your friend ... or I am Your enemy !

nid69ita

@silente, per me la differenza più grande è che una #define per una costante NON ne definisce il tipo.
Ovvero se io creo    #define MIONUM 10              non ho detto se quel 10 è int, long o altro.
Invece una const comunque vuole il tipo. E quindi il compilatore non "interpreta" ma del tipo del dato lo hai informato tu.  
my name is IGOR, not AIGOR

Standardoil

#6
Feb 07, 2019, 03:30 pm Last Edit: Feb 07, 2019, 03:53 pm by Standardoil
No, fermi, const alloca memoria
Che poi il compilatore non ti lascia più modificare, li dove la hai "const"....atata
Ma magari in altri moduli, sì
Ovvero una variabile può essere const in un modulo, in una specifica funzione, ma non in un'altra
Rimangono variabili, che possono essere dichiarate extern in altri moduli, che possiedono un indirizzo e che possono essere passate per riferimento in C++ (questo non sono sicuro, non programmo in C++)
e aggiungo, passo ad una funzione l'indirizzo di una const, la funzione lo tratta come un puntatore a variabile, ecco modificata una const senza nemmeno doverla dichiarare extern in un altro modulo
Prima legge di Nelson (che sono io): La risposta giusta si può ottenere solo dalla domanda giusta, domande sbagliate danno risposte inutili

Non bado a studenti, che copino altrove

Hai problema-Ti domando-Non rispondi: Non ti serve più

gpb01

#7
Feb 07, 2019, 03:51 pm Last Edit: Feb 07, 2019, 03:51 pm by gpb01
No, fermi, const alloca memoria ...
... lo hai letto il thread che ho linkato al mio post #1 ? ... mi sembra di no ... ::)

Guglielmo
Search is Your friend ... or I am Your enemy !

docdoc

Oltre alla lettura del link di Guglielmo, intanto c'è la logica, ossia se io ho una
#define VALORE 584
quel simbolo (VALORE) il compilatore lo sostituisce in tutto il codice quando compila.
Per cui basta fare qualche prova ad esempio:

Code: [Select]
#define VALORE 584
void setup() {
  int p = VALORE;
  p += VALORE;
  Serial.println(VALORE);
}


equivale a:

Code: [Select]
void setup() {
  int p = 584;
  p += 584;
  Serial.println(584);
}


Entrambi (Arduino UNO) occupano esattamente 1600 byte per il programma e 188 byte di RAM.

Usare la const ossia:

Code: [Select]
const int VALORE = 584;
void setup() {
  int p = VALORE;
  p += VALORE;
  Serial.println(VALORE);
}


porta sempre a 1600 byte di programma e 188 byte di RAM.
Si può "risparmiare" invece qualcosa se il valore ad esempio fosse un byte:

Code: [Select]
const byte VALORE = 84;
void setup() {
  int p = VALORE;
  p += VALORE;
  Serial.println(VALORE);
}


che porta il programma a 1416 byte e sempre 188 di RAM.

In sostanza quindi non c'è quasi differenza (anche se io preferisco in genere le #define perché per convenzione i simboli sono in maiuscolo e li distinguo così dalle variabili normali).
Alex "docdoc"
- "Qualsiasi cosa, prima di rompersi, funzionava"

Standardoil

#9
Feb 07, 2019, 04:15 pm Last Edit: Feb 07, 2019, 04:15 pm by Standardoil
... lo hai letto il thread che ho linkato al mio post #1 ? ... mi sembra di no ... ::)

Guglielmo
invece si, letto. Anzi già letto in precedenza
In cosa contrasta con quello che ho detto io?
Forse che non puoi passare l'indirizzo di una const?
Forse che non puoi avere un puntatore a const?
Forse che non puoi eguagliare un puntatore a variabile all'indirizzo di una const?
Tutte queste cose non si fanno con le #define
Prima legge di Nelson (che sono io): La risposta giusta si può ottenere solo dalla domanda giusta, domande sbagliate danno risposte inutili

Non bado a studenti, che copino altrove

Hai problema-Ti domando-Non rispondi: Non ti serve più

SukkoPera

#10
Feb 07, 2019, 04:27 pm Last Edit: Feb 07, 2019, 04:37 pm by SukkoPera
@silente, per me la differenza più grande è che una #define per una costante NON ne definisce il tipo.
Ovvero se io creo    #define MIONUM 10              non ho detto se quel 10 è int, long o altro.
Invece una const comunque vuole il tipo. E quindi il compilatore non "interpreta" ma del tipo del dato lo hai informato tu.   
Questo è il punto principale!

Inoltre, una const in teoria alloca memoria, ma un compilatore un po' sveglio è in grado di evitarlo facendo la stessa sostituzione che farebbe con una #define. Da qualche parte gpb aveva anche fatto un test di disassembly per provare questo.

In sostanza: meglio una const ovunque possibile, almeno eventuali errori di tipo sono subito beccati dal compilatore. Dove non è possibile, si va di #define.

Un ultimo dettaglio: l'uso ad oltranza di #define è tipico del C, perché non è possibile fare questo:
Code: [Select]
const int N = 10;
char str[N] = "ciao";

... in quanto gli array devono avere una dimensione fissa e nota a tempo di compilazione (e const significa più "a sola lettura" che "costante"). In C++, invece, la cosa è perfettamente legale, per cui si assiste ad utilizzi di #define più limitati. In teoria, il C++ prevede anche l'uso delle funzioni inline al posto delle macro (cosa poi introdotta anche in C99, mi pare), proprio per eliminare il più possibile i #define, che spesso sono causa di errori e/o incasinamenti generali.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

gpb01

#11
Feb 07, 2019, 04:29 pm Last Edit: Feb 07, 2019, 04:31 pm by gpb01
In realtà, se nella #define tu specifichi il tipo (invece che lasciare int di default), ecco che NON risparmi un bel nulla e le due cose tornano equivalenti:

Code: [Select]
#define VALORE (byte)84
void setup() {
 int p = VALORE;
 p += VALORE;
 Serial.println(VALORE);
}

... ti darà la stessa occupazione del tuo "const byte VALORE = 84;" :D

Guglielmo

Search is Your friend ... or I am Your enemy !

gpb01

#12
Feb 07, 2019, 04:30 pm Last Edit: Feb 07, 2019, 04:31 pm by gpb01
invece si, letto. Anzi già letto in precedenza
In cosa contrasta con quello che ho detto io?
... guarda COSA ho quotato ... pare che qualcuno avesse detto che const non alloca memoria ...

Guglielmo
Search is Your friend ... or I am Your enemy !

Datman

#13
Feb 07, 2019, 05:00 pm Last Edit: Feb 07, 2019, 05:03 pm by Datman
... perciò, dagli esperimenti di docdoc al #8 e da quanto detto da SukkoPera al #10:

"Inoltre, una const in teoria alloca memoria, ma un compilatore un po' sveglio è in grado di evitarlo facendo la stessa sostituzione che farebbe con una #define."

sembra che, senza offesa, l'IDE non sia "un po' sveglio"... :)
Hi,I'm Gianluca from Roma.I play&work with electronics since I was16(1984).
After 25yrs of maintenance on cameras&video mixers,since 2013myJob is HDTVstudios design.
Since Jan2015 IPlayWith Arduino:bit.ly/2F3LPWP
Thanks 4 a Karma if U like my answer

gpb01

#14
Feb 07, 2019, 05:02 pm Last Edit: Feb 07, 2019, 05:03 pm by gpb01
sembra che, senza offesa, l'IDE non sia "un po' sveglio"... :-)
No, sei TU che stai sbagliando ... 84 così senz'altra specifica è un "int" (che è il tipo di default se non si specifica nulla), mentre nella tua "const" tu per 84 specifichi chiaramente che vuoi un byte e allora ... devi specificarlo anche nella #define.

Guglielmo
Search is Your friend ... or I am Your enemy !

Go Up