A volte è necessario avere tabelle (grandi o piccole) nel codice sorgente.
ItemType const SomeTable[] = {
// id name min max
ITEM( 3, "Foo", 70, 180),
ITEM(13, "Bar", 30, 50),
ITEM(14, "Baz", 30, 60),
ITEM(60, "Abc", 1, 4),
};
Nel tempo sono state aggiunte nuove righe e quelle esistenti sono state modificate:
ItemType const SomeTable[] = {
// id name min max
ITEM( 3, "Foo", 70, 180),
ITEM(13, "BetterBar", 30, 50),
ITEM(14, "Baz", BAZ_MIN, BAZ_MAX),
ITEM(60, "Abc", 1, 4),
ITEM(80, "AAAAAA", 0, A_COUNT),
ITEM(81, "BBB BBBB B", 0, B_COUNT),
};
Sembra orribile. Possiamo correggere l'allineamento:
ItemType const SomeTable[] = {
// id name min max
ITEM( 3, "Foo" , 70, 180),
ITEM(13, "BetterBar" , 30, 50),
ITEM(14, "Baz" , BAZ_MIN, BAZ_MAX),
ITEM(60, "Abc" , 1, 4),
ITEM(80, "AAAAAA" , 0, A_COUNT),
ITEM(81, "BBB BBBB B", 0, B_COUNT),
};
Sembra migliore, ma il cambiamento effettivo è perso. Se si guarda il diff di controllo della versione, è quasi impossibile vedere cosa è stato aggiunto quando l'intera tabella è stata riscritta. Ciò è particolarmente grave se le tabelle sono diverse centinaia di righe, come tendono a essere.
È possibile stimare le dimensioni delle tabelle in anticipo, ma in pratica tendono a non essere attive: o troppo piccole, nel qual caso sono inutili o troppo grandi, nel qual caso viene persa molta leggibilità.
Sicuramente qualcuno ha trovato una buona strategia per gestire questi casi. Non deve essere un sistema perfetto, purché sia ragionevolmente leggibile.
Le seguenti cose sono fuori dallo scopo della domanda:
-
Uso di file di dati esterni: la piattaforma di destinazione potrebbe non avere il file system.
-
Utilizzo di uno script di conversione / conversione esterno per convertire il file di dati in codice: introduce una dipendenza aggiuntiva, che potrebbe non essere possibile o preferibile.
Vorrei mantenere questa domanda in modo agnostico, ma la situazione tipica in cui ho questo problema è nei progetti C incorporati. Ad esempio, una libreria di scopi speciali per diverse piattaforme. Quindi fondamentalmente ho solo il preprocessore a mia disposizione, e X-macros va solo lontano.