Почему нельзя инициализировать переменную результатом вызова функции в си?

Насколько я понял в Си не работает динамическая инициализация для переменных со статической продолжительностью хранению, как в С++. То есть я не могу сделать вот так:

int one()
{ return 1; }

int a = one();

int main()
{
   return 0;
}

MSVC ругается на то, что я должен инициализировать переменную a, константой.
И ради интереса я решил сделать так:

const int one()
{ return 1; }

Тут если я все правильно понял функция вернет не просто (int)1, а (const int)1. Но и это тоже не работает. Из этого я и делаю вывод: "В Си не работает динамическая инициализация для переменных со статической продолжительностью хранению", или все таки этому явлению есть другое объяснение?


Ответы (3 шт):

Автор решения: Генс
/*
Только так. Функция не может возвращать то чего у неё нет.
*/
#include <stdio.h>
#include <windows.h>
float matematika(float a,float b);
float matematika(float a,float b)
{
static float d=3.14;
float c=a+b;
c*=d
return c;
}
int main(void)
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
float x,y;
//float z=matematika(x,y);// Так не работает.
    printf("Ввод 2-х чисел с плавающей точкой\n");
scanf (" %f %f",&x,&y);
float z=matematika(x,y);//Только так.
    printf("Ответ:%.2f\n",z);
    return 0;
}
→ Ссылка
Автор решения: nekida
  1. Как уже говорилось, у вас "a" является глобальной переменной. А глобальные переменные инициализируются до этапа выполнения программы.
  2. Чтобы получить результат из функции "one()", ее надо выполнить, а как вы собрались это сделать, если эта строчка даже не выполнится? Процессор выполняет функции, а чтобы начать выполнять функцию нужно использовать стек, сохранить текущие состояние программы перед переходом, сделать переход и т.д. Всего этого у вас нет.

"Строительными блоками" в языке Си все же являются функции, а точнее, их тела, выполняемые процессором, в то время, как переменные просто копируются в память.

→ Ссылка
Автор решения: AlexGlebe

Читаем стандарт

5.1.2 Execution environments

Two execution environments are defined: freestanding and hosted. In both cases, program startup occurs when a designated C function is called by the execution environment. All objects with static storage duration shall be initialized (set to their initial values) before program startup. The manner and timing of such initialization are otherwise unspecified. Program termination returns control to the execution environment.

5.1.2 Среда выполнения

Определены две среды выполнения: автономная и помещенная. В обоих случаях запуск программы происходит, когда назначенная функция C вызывается средой выполнения. Все объекты со статической продолжительностью хранения должны быть инициализированы (установлены на их начальные значения) перед запуском программы. В других случаях способ и время такой инициализации не указаны. Завершение программы возвращает управление среде выполнения.

6.7.9 Initialization

All the expressions in an initializer for an object that has static or thread storage duration shall be constant expressions or string literals.

6.7.9 Инициализация

Все выражения в инициализаторе для объекта, который имеет статическую длительность хранения или поточную, должны быть константными выражениями или строковыми литералами.

То-есть данные должны быть установлены компилятором перед запуском программы. И быть константами. То есть не вычисляться напрямую.

→ Ссылка