Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - [Prerprocessore]Limiti e potenzialità
Forum - C/C++ - [Prerprocessore]Limiti e potenzialità

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
Roby94 (Member)
Guru


Messaggi: 1170
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 15:47
Venerdì, 11/12/2015
Buondì, apro questo topic per la difficoltà di riperimento di informazioni utili. Vorrei cercare di capire quali siano i limiti del preprocessore, l'ho sempre sfruttato poco, piccole macro, include e poco altro. A suo tempo mi fu insegnato che il preprocessore puo eseguire piccole funzioni prima dell'effettiva compilazione del programma, riducendo in alcuni casi il peso computazionale di alcune operazioni in runtime. Affermazione che oggi mi sembra molto enfatizzata.
Propongo un esempio, devo calcolare degli indirizzi di alcuni registri nella forma
Codice sorgente - presumibilmente Plain Text

  1. (op?0x80:0x00)|(address<<1)


op e address non sono variabili, cioè vengono definiti prima della compilazione, se dovessi adoperare questo codice sostituendo op e address per ogni ricorrenza ovviamente la condizione lo shift e l'or verrebbero eseguiti in runtime, uno spreco! Quindi ho pensato, passiamo la palla al preprocessore
Codice sorgente - presumibilmente C/C++

  1. #define regAddress(address, op) (op?0x80:0x00)|(address<<1)


Ripensandoci però non ho ricolto niente, se io richiamassi regAddress in qualche parte del codice address e op sarebbero comunque considerate delle variabili, non potendo eseguire le operazioni richieste prima della compilazione.
Ora mi chiedo, esiste un modo per dire a precompilatore di risolvere tutta l'equazione e non limitarsi ad un semplice copia incolla, o mi devo armare di pazienza e modificare manualmente ogni singola invocazione di regAddress.
Mi duole porre una domanda, cosi banale ma non ho mai avuto occasione di approfondire l'argomento preprocessore, causa anche la diffusione un po' caotica del materiare in argomento su internet.
Vi ringrazio in anticipo.

PM Quote
Avatar
pierotofy (Admin)
Guru^2


Messaggi: 6230
Iscritto: 04/12/2003

Segnala al moderatore
Postato alle 16:19
Venerdì, 11/12/2015
Codice sorgente - presumibilmente C++

  1. #if op == 0x80
  2.    #define regAddress(....
  3. #elif op == 0x00
  4.    #define regAddress(....
  5. #endif



https://gcc.gnu.org/onlinedocs/gcc-3.0.2/cpp_4.html#SEC38

Occhio però, i compilatori di oggi sono piuttosto intelligenti ed è molto probabile che queste ottimizzazioni siano già state eseguite a tua insaputa! Disassembla un piccolo programma di esempio e vedi se questo è il caso.

Assicurati inoltre di seguire best practices se usi macro e di circondare le tue espressioni tra parentesi (sempre!)

Codice sorgente - presumibilmente C/C++

  1. #define regAddress(address, op) ((op?0x80:0x00)|(address<<1))



Altrimenti espressioni come questa:

Codice sorgente - presumibilmente Plain Text

  1. regAddress(0x00, 0)++;



Diventano:

Codice sorgente - presumibilmente Plain Text

  1. (op?0x80:0x00)|((address<<1)++)



Invece di:

Codice sorgente - presumibilmente Plain Text

  1. (op?0x80:0x00)|(address<<1))++



Il mio blog: https://piero.dev
PM Quote
Avatar
Roby94 (Member)
Guru


Messaggi: 1170
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 16:31
Venerdì, 11/12/2015
Grazie Piero, in effeti hai ragione, il precompilatore fa quello che desideravo. Ma quali sono gli effettivi limiti di questo? Fino a che punto arriva, prima di passare a far eseguire il codice in runtime?

PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1620
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 18:23
Venerdì, 11/12/2015
Tieni conto, che come dice piero anche un compilatore C come tcc usa l'ottimizzazione per constant propagation: https://en.wikipedia.org/wiki/Constant_folding quindi l'utilizzo delle macro per sostituire la constant propagation ad oggi è abbastanza inutile.....

PM Quote
Avatar
Roby94 (Member)
Guru


Messaggi: 1170
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 18:44
Venerdì, 11/12/2015
Ok, grazie, allora mi sto facendo problemi per nulla.

PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 449
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 22:14
Venerdì, 11/12/2015
Se stai usando un compilatore che supporta lo standard C++11 o maggiore, puoi fare
Codice sorgente - presumibilmente C++

  1. constexpr unsigned int regAddress(bool op, unsigned int address)
  2. {
  3.     return op ? 0x80:0x00 | (address<<1);
  4. }


Ho usato unsigned int ma non so quale sia il tipo che ti va bene.
In ogni caso la funzione viene calcolata a compile time, hai in più i vantaggi di scope hiding delle funzioni.

PM Quote
Avatar
Roby94 (Member)
Guru


Messaggi: 1170
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 23:28
Venerdì, 11/12/2015
Grazie, in accordo con i post precedenti che differenze corrono tra constexpr e inline?

PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 449
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 23:38
Venerdì, 11/12/2015
inline significa che il compilatore è incoraggiato a eliminare il frame di chiamata della funzione (ossia la parte di push/pop dei parametri e altre cose).
Constexpr invece dice che la funzione può essere eseguita dal compilatore (è utile nel C++ di oggi per utilizzare funzioni all'interno dei template).
Non saprei farti esempi non banali ora, ti conviene cercare su internet degli utilizzi di constexpr (in genere quelli interessanti sono piuttosto avanzati).

PM Quote
Avatar
Roby94 (Member)
Guru


Messaggi: 1170
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 23:48
Venerdì, 11/12/2015
Non avevo fatto caso al fatto che avessi scritto C++, io ora sto compilando in C.

Edit:
Usando inline il tutto viene sostituito con un semplice LDI e STS, quindi la macro e la funzione inline portano allo stesso risultato ottimizzato.

Ultima modifica effettuata da Roby94 il 11/12/2015 alle 23:53
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo