Cioè, no... è il mio solito gioco di parole
però è una macro che controlla se due oggetti (variabili, no costanti letterali) sono tra di loro uguali
stavo vedendo di fare un'accrocchio per salvare, caricare, ordinare, cercare ed eliminare da file delle strutture, il più generico possibile, ispirato da una discussione recente, qui sul forum
per intanto che stavo scrivendo un po' di funzioni base mi è venuto in mente di fare una funzione di verifica di eguaglianza di strutture generiche (intendiamoci: variabili istanza di struttura qualsiasi)
e mi è venuto in mente che se lo faccio come macro, invece che come funzione, non ho bisogno di conoscere il tipo di variabile, e posso scriverla completamente generica
ecco quindi la macro che date due variabili qualsiasi vi dice se sono "uguali bit a bit"
e in 'C' se sono uguali bit a bit sono uguali: punto.
quindi con questa macro è possibile testare l'eguaglianza di oggetti di qualsiasi tipo, anche "non proprio uguali fra loro"
mi spiego:
per prima cosa gli argomenti della macro devono essere degli oggetti che possiedono un indirizzo, ovvero variabili, anche "const", ma indirizzabili
per seconda cosa, non serve di conoscere il tipo, la macro confronta bit a bit il "contenuto" della variabile passata come argomento
per terza cosa non serve che i due argomenti siano dello stesso tipo, il test si interrompe al termine del primo argomento
la cosa è voluta:
ipotizziamo di lavorare con generiche strutture
anche in 'C' esiste un concetto minimale di ereditarietà, non solo in C++
è sufficiente "creare" una struttura-di-classe derivata (mi si passi il termine quasi ereditato dal C++) come un'estensione della struttura-di-classe base
faccio un esempio
prendiamo una scuola: docenti, bidelli, alunni
sono tutti persone
typedef struct {
char nome[50];
char cognome[50];
char datanascita[10];
} persona;
e con questo abbiamo creato la struttura-di-classe delle persone
vogliamo che i dipendenti siano persone con uno stipendio
typedef struct {
persona pers;
int stipendio;
} dipendente;
e che i docenti siano dipendenti che insegnino una e una sola materia
typedef struct {
dipendente dip;
char materia[10];
} docente;
abbiamo creato tre struct, che come le classi del C++ ereditano ciascuna dalla precedente
ecco che usando la mia macro e ricordando di usare le classi primitive come primo argomento e le derivate come secondo, è possibile confrontare per eguaglianza persone con docenti, dato che il confronto bit a bit si interrompe al termine della struttura persona, che si ripete uguale anche per i dipendenti e per i docenti
parimenti sarà possibile confrontare dipendenti con docenti (anche se non docenti con dipendenti o docenti con bidelli)
dopo tanto parlare ecco che arriva la macro che compara oggetti indirizzabili,
occhio che si tratta del mio solito "Militar Grade Code": materiale per armi nucleari, mica codice annacquato.....
#define uguali(A , B) ({int ret=1; size_t dimensione = sizeof A; for (size_t i = 0; i < dimensione; i++) { if ((* (byte *) &A + i) != (* (byte *) &B + i)) { ret = 0; break; } } ret;})
e anche un programma minimale di demo
// di Nelson-StandardOil
// IDE 1.8.13
// Progetto: macro generica di confronto oggetti
// Scopo:
// Data inizio lavori:
typedef struct tipo_s
{
int a;
int b;
} tipo;
#define uguali(A , B) ({int ret=1; size_t dimensione = sizeof A; for (size_t i = 0; i < dimensione; i++) { if ((* (byte *) &A + i) != (* (byte *) &B + i)) { ret = 0; break; } } ret;})
tipo v1 = {1, 2};
tipo v2 = v1;
void setup(void)
{
Serial.begin(9600);
Serial.println("start");
if (uguali(v1, v2))
{
Serial.println("Uguali");
}
else
{
Serial.println("Diversi");
}
int h1 = 1;
double h2 = 1;
if (uguali(h2, h1))
{
Serial.println("Uguali");
}
else
{
Serial.println("Diversi");
}
}
void loop(void)
{
}