Pagina 1 di 2

Global "static" in C99

MessaggioInviato: 21 mag 2014, 22:38
da Shockwaver
Salve a tutti.
Chiedo scusa se alla domanda la prima risposta che vi viene in mente è UTFG o "apri la prima IDE che hai sotto mano e controlla da te", ma diciamo che sono più alla ricerca di un.. conforto o per meglio dire una spiegazione/risorsa che possa una volta per tutte dirmi tutto quello che c'è da dire su questa keyword quando utilizzata con scope globale.

Allora (chiedo scusa per la congiunzione coordinante conclusiva ad inizio di frase, ma mi aiuta a riordinare le idee), ciò che io so è che, quando è usata come modificatore in una dichiarazione globale, rende l'oggetto della dichiarazione "statica" (visibile) solo all'unità di compilazione. Fino a quando parliamo di variabili di dati il tutto fila liscio, è come un "private" in OOP.
Il cervello però mi si ingrippa un po' quando passiamo alle funzioni. Il concetto è lo stesso, ma questo significa per caso che i prototipi non li posso dichiarare in un file a parte o lo static si applica solo all'implementazione della funzione e non alla dichiarazione?

Faccio un esempio, questo è legale?

File MyHeader.h
Codice: Seleziona tutto
static void aFunction(void);


File MySourceFile.c
Codice: Seleziona tutto
#include "MyHeader.h"

int main(int argc, **argv)
{
    aFunction();

    return 0;
}

static void aFunction(void)
{
    return;
}


In altre parole ciò che mi sfugge è: un file header .h è considerato unità di compilazione a sé stante o l'include lo fa diventare parte integrante dell'unità di compilazione dove viene incluso?
Perché se fosse a sé stante, il prototipo e l'implementazione devono risiedere nello stesso file, altrimenti posso smazzarli in giro.

Ringrazio in anticipo chi ha avuto la bontà di leggere fin qui e chi vorrà aiutarmi a dipanare questo dubbio.
O_/

Re: Global "static" in C99

MessaggioInviato: 21 mag 2014, 22:49
da TardoFreak
Stai facendo confusione.
O meglio, hai inverito le cose.
Le variabili statiche sono quelle dichiarate all' interno delle funzioni. Hanno la caratteristica di non essere allocate nello stack di volta in volta ma solo la prima volta che viene chiamata la funzione.
In pratica la funzione ha una sorta di variabile globale ma visibile solo al suo interno.
Va da se che una funzione con una o più variabili statiche non è "thread safe", non è rientrante.

Le funzioni dichiarate statiche sono semplicemente visibili all' interno del modulo di cui fanno parte.

Edit: dichiarare le funzioni come statiche è una cosa ottima, serve per nascondere il codice, il cosiddetto "information hiding". Sulle variabili statiche, personalmente, non le amo molto perché rendono la funzione non rientrante.

Re: Global "static" in C99

MessaggioInviato: 21 mag 2014, 22:51
da Shockwaver
Nono mi stavo riferendo a ciò che dichiari static non all'interno di una funzione..
Le static all'interno di una funzione garantiscono la ritenzione dei dati ecc ecc quello che dicevi tu, ma a me interessavano le dichiarazioni di variabili e funzioni globali

In una funzione una variabile sia static che non è comunque visibile solo nella funzione stessa..

Re: Global "static" in C99

MessaggioInviato: 21 mag 2014, 22:53
da Shockwaver
Per rispondere al tuo edit:
Esattamente quello a cui servono a me! Mi chiedevo solo se posso prototiparle in file differenti da dove vengono implementate..

Edit: a me invece la variabili globali static mi piacciono per lo stesso motivo per cui mi piacciono le funzioni static.. non sono visibili altrove, neanche con un extern..

Re: Global "static" in C99

MessaggioInviato: 21 mag 2014, 22:54
da TardoFreak
Per le funzioni ti ho già risposto ma non ho capito il tuo ultimo intervento. :-M
Cosa intendi per prototiparle in file differenti e a che scopo?
Per le variabili non lo so, non ho mai dichiarato variabili globali come static. Non ne vedo la necessità.
Poi magari c'è e forse sono io che sono ignorante. :?

Re: Global "static" in C99

MessaggioInviato: 21 mag 2014, 23:02
da Shockwaver
Shockwaver ha scritto:Edit: a me invece la variabili globali static mi piacciono per lo stesso motivo per cui mi piacciono le funzioni static.. non sono visibili altrove, neanche con un extern..


Avrei bisogno di raccogliere tutti i prototipi di alcune funzioni all'interno di un file header (invece che ammucchiarle all'inizio del file .c) da includere in un file .c e vorrei che queste funzioni siano static quindi visibili solo all'interno dell'unità di compilazione dove vengono IMPLEMENTATE.

Re: Global "static" in C99

MessaggioInviato: 21 mag 2014, 23:04
da DirtyDeeds
Sì, puoi dichiararle anche in un header: l'header viene incluso e costituisce una singola unità di compilazione insieme al file C.

Per esempio, questo è un estratto di un mio header dove ci sono delle dichiarazioni static per delle funzioni (sì, lo so che non bisognerebbe dichiarare simboli che inizino per underscore perché riservati per il C ;-) ):

Codice: Seleziona tutto
static void __tile_rectangleT(int, int, tiling_search_t *, tile_t *);
static void __tile_rectangleT1(int, int, tiling_search_t *, tile_t *);
static void __tile_rectangle(int, int, int, tiling_search_t *, tile_t *);


E questo è l'inizio della definizione fatta in un file .c

Codice: Seleziona tutto
static void __tile_rectangleT(int level, int width, tiling_search_t *search_data, tile_t *tiling)
{
    if (width == 0) {
        search_data->level = level;
        longjmp(search_data->env, 1);
    }


Quando ci sono queste situazioni, io in genere preparo due header: uno pubblico, per l'interfaccia del modulo, e uno privato. Quindi per esempio nel file .c di cui sopra c'è l'inclusione:

Codice: Seleziona tutto
#include "tiling_private.h"


ma il programma principale includerà

Codice: Seleziona tutto
#include "tiling.h"

Re: Global "static" in C99

MessaggioInviato: 21 mag 2014, 23:04
da TardoFreak
Quindi soltanto per un motivo di ordine e leggibilità del sorgente?
Se è così le puoi benissimo raccogliere dentro un file qualsiasi ed includerlo (esclusivamente) nel modulo a cui appartengono.

Re: Global "static" in C99

MessaggioInviato: 21 mag 2014, 23:06
da Shockwaver
DirtyDeeds ha scritto:Quando ci sono queste situazioni, io in genere preparo due header: uno pubblico, per l'interfaccia del modulo, e uno privato. Quindi per esempio nel file .c di cui sopra c'è l'inclusione:

Codice: Seleziona tutto
#include "tiling_private.h"


ma il programma principale includerà

Codice: Seleziona tutto
#include "tiling.h"


FANTASTICO. Hai centrato esattamente il punto della mia domanda, mi stavo apprestando a fare proprio questo!
Grazie mille, NUOVAMENTE, a entrambi.

Re: Global "static" in C99

MessaggioInviato: 21 mag 2014, 23:07
da Shockwaver
TardoFreak ha scritto:Quindi soltanto per un motivo di ordine e leggibilità del sorgente?
Se è così le puoi benissimo raccogliere dentro un file qualsiasi ed includerlo (esclusivamente) nel modulo a cui appartengono.

Esatto, mi chiedevo appunto se fosse possibile, aka, se un file .c dove includi un file .h rappresentasse un'unica unità di compilazione.

Grazie ancora.