Nel linguaggio C non c'è supporto per le funzioni annidate a livello di standard ANSI/ISO. Storicamente, C è stato progettato come un linguaggio compatto, vicino all'hardware, dove la funzione esisteva a livello superiore dell'unità di traduzione (file). A differenza di linguaggi come Pascal, C non consente di dichiarare una funzione all'interno di un'altra funzione puramente sintatticamente.
Il problema che si presenta agli programmatori: spesso si desidera utilizzare funzioni di supporto locali, visibili solo all'interno di una funzione per incapsulare la logica o evitare la duplicazione del codice. Il supporto integrato per l'annidamento consentirebbe di ridurre l'ambito di visibilità e rendere il codice più modulare.
Uno dei modi più popolari per risolverlo è utilizzare funzioni statiche (static) a livello di file, oppure passare puntatori a funzioni esterne, o imitare l'annidamento tramite strutture con funzioni di callback. Se è necessario un "closure" del contesto, si possono utilizzare strutture con puntatori ai dati (analogo a closure).
Esempio di imitazione di una funzione "locale" tramite passaggio di puntatore:
#include <stdio.h> static int helper(int x) { return x * x; } void myFunction(void) { printf("Il quadrato del numero 5: %d ", helper(5)); }
Caratteristiche chiave:
È possibile definire una funzione interna all'interno di un'altra funzione nel C standard e chiamarla?
No. Nel linguaggio C (standard ANSI/ISO) non è possibile dichiarare una funzione all'interno di un'altra funzione. Tentare di farlo porterà a un errore di compilazione. Alcune estensioni non standard (ad esempio, GCC) lo permettono, ma tali programmi non saranno portabili.
Possono le funzioni statiche sostituire completamente le funzionalità delle funzioni annidate in termini di significato e sicurezza?
Le funzioni statiche limitano l'ambito di visibilità alla funzione-file, ma non alla funzione-blocco. Questo significa che le funzioni statiche sono accessibili da qualsiasi codice nello stesso file, il che non garantisce una completa incapsulazione come nel caso delle vere funzioni annidate.
Si possono implementare "closure" in funzioni annidate in C puro?
No, direttamente non c'è tale supporto. Tuttavia, si possono usare strutture contenenti un puntatore ai dati e una funzione, il che avvicina il comportamento a una closure:
typedef struct { int context; int (*func)(int, int); } closure; int add(int a, int b) { return a + b; } closure cl = { .context = 5, .func = add };
Uno sviluppatore utilizza un'estensione GCC - dichiara funzioni interne nel progetto, dopo di che il codice non si compila su MSVC e altri compilatori.
Vantaggi:
Svantaggi:
Uno sviluppatore per tutte le funzioni di supporto limita l'ambito di visibilità a static, utilizza una struttura per passare il contesto.
Vantaggi:
Svantaggi: