В вашей статической версии будет только одна переменная, которая будет где-то храниться, и всякий раз, когда функция выполняется, будет использоваться точно такая же переменная. Даже для рекурсивных вызовов.
Нестатическая версия будет храниться в стеке для каждого вызова функции и уничтожаться после каждого.
Теперь ваш пример немного сложен в том, что на самом деле делает компилятор, поэтому давайте сначала рассмотрим более простой случай:
void foo() {
static long i = 4;
--i;
printf("%l\n", i);
}
А потом главное что-то вроде этого:
int main() {
foo();
foo();
return 0;
}
напечатает
3
2
, тогда как с
void foo() {
long i = 4;
--i;
printf("%l\n", i);
}
будет напечатано
3
3
Теперь в вашем примере у вас есть const, поэтому значение не может быть изменено, поэтому компилятор может воспроизвести некоторые трюки, хотя это часто не влияет на сгенерированный код, но помогает компилятору обнаруживать ошибки. Кроме того, у вас есть указатель, и имейте в виду, что статика влияет на сам указатель, а не на значение, на которое он указывает. Таким образом, строка «привет» из вашего примера, скорее всего, будет помещена в сегмент .data вашего бинарного файла и всего один раз и будет жить столько, сколько длится программа, независимо от статичности.