la macro che è uguale alla macro che è uguale ......

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)
{
}

e naturalmente lo ho appena postato che mi è venuto in mente come estenderlo a oggetti qualsiasi, ovvero anche a costanti letterali e/o oggetti non indirizzabili

ma questo lo lasciamo come concorso tra i lettori

I tuoi post sono sempre molto interessanti e stimolanti, però ammetto che mi sfugge un po' il senso di confrontare oggetti che per definizione sono diversi :o
Ciò detto, non puoi ottenere un risultato "simile" anche con l'uso di memcmp()?

Grazie, molto onorato, specialmente detto da uno bravo

Il confrontare oggetti di tipo differente è per mostrare l'ereditarietà in 'C'

Invece per la memcmp():

Hai pienamente ragione, ma la vedo meno immediata come uso, serve di passare due indirizzi e una lunghezza

E poi, se uno passa da questo post e 'studia' può trarre più di una ispirazione

Questo è lo scopo ultimo

Standardoil:
E poi, se uno passa da questo post e 'studia' può trarre più di una ispirazione

Su questo non ci sono dubbi! :slight_smile:

Interessante la sintassi. Interessante anche il "concetto" di ereditarietà riferito al C.

ciao a Tutti,

domanda seria…questi li considerate uguali?:

unsigned int a = 32768;
int b = -32768;

oppure:

byte a = 48;
char b = '0';

risposta seria:

se vuoi provo...

aggiornamento serio:

li considera uguali, tutte e due le coppie
in effetti si tratta di valori uguali bit a bit
e qui si tratta di un compromesso, ereditarietà e flessibilità nel controllo di strutture
contro qualche problema con alcuni tipi dati

che poi credo sia solo tra signed ed unsigned, comunque importante da tenere presente