Il problema delle variabili globali è appunto il fatto che possono essere modificate da dovunque, il che rende difficile seguirne i possibili stati e individuare come/dove possono cambiare. D'altra parte per certi oggetti (tipicamente dei singleton contenenti un qualche genere di stato globale dell'applicazione) possono essere utili, specie se l'alternativa sarebbe continuare a passarseli in giro in praticamente ogni chiamata a funzione.
Per le funzioni static, in genere non sono una buona idea, poiché associano un singolo stato ad una funzione che potrebbero chiamare più procedure; esempio stupido: la strtok. Se tra una chiamata alla strtok già "inizializzata" e l'altra si chiama un'altra procedura che al suo interno fa uso della funzione in questione ovviamente succederà un gran pasticcio, dato che una variabile static è uno stato condiviso per tutto il programma nascosto in una funzione. Non a caso di buona parte delle funzioni della libreria C che fanno uso di tali funzionalità sono state scritte delle versioni "rientranti" che non presentano questo problema, in genere esternalizzando lo stato in una qualche struttura fornita dal chiamante.
Per dirla in altre parole: spesso static è usato per avere una specie di "classe dei poveri" (per memorizzare membri privati, ...), ma dato che se ne può avere solo una singola copia è facile fare casino nel momento in cui più parti del codice usano la funzione in questione.