инициализация статического объекта в функции
От: vopl Россия  
Дата: 16.01.08 09:14
Оценка:
Начал тут портировать чудо-прогу c msvc на gcc и наткнулся на такой затык

#include <stdio.h>

void f2();
static int f1()
{
    printf("f1\n");
    f2();// тут
    return 1;
}

void f2()
{
    printf("f2\n");
    static int stub = f1();// и тут
}
int main()
{
    f2();

    return 0;
}


msvc выводит

f2
f1
f2


а gcc уходит в рекурсию

в строке
static int stub = f1();

вызов f1 производится многократно за счет того что повторный вызов f2 происходит ранше присваивания переменной stub, тоесть на момент повторного вызова f2 еще не случилось не одного присваивания в переменную stub и она, типа еще не инициализирована


Тут подумал немного и вот чего написал

#include <stdio.h>

void f2();
static int f1()
{
    printf("f1\n");

    static int cnt(0);
    if(cnt++ < 10)
    {
        f2();
    }
    return 1;
}

void f2()
{
    printf("f2_beg\n");
    static const int stub = f1();
    printf("f2_end\n");
}
int main()
{
    f2();

    return 0;
}


— таким образом присваиваю константной переменной несколько раз. Поэтому интуитивно думаю что gcc не прав в способе инициализации статического объекта, а msvc прав

... a потом еще подумал немного и вот чего написал


#include <stdio.h>

struct SStatic
{
    SStatic(int i)
    {
        printf("ctor %d, 0x%p\n",i, this);
    }
    ~SStatic()
    {
        printf("dtor 0x%p\n", this);
    }
};

void f2();
static int f1()
{
    printf("f1\n");

    static int cnt(0);
    if(cnt++ < 10)
    {
        f2();
    }
    return cnt;
}

void f2()
{
    printf("f2_beg\n");
    static const SStatic stub = f1();
    printf("f2_end\n");
}
int main()
{
    f2();

    return 0;
}


и ужаснулся

f2_beg
f1
f2_beg
f1
f2_beg
f1
f2_beg
f1
f2_beg
f1
f2_beg
f1
f2_beg
f1
f2_beg
f1
f2_beg
f1
f2_beg
f1
f2_beg
f1
ctor 11, 0x00404030
f2_end
ctor 11, 0x00404030
f2_end
ctor 11, 0x00404030
f2_end
ctor 11, 0x00404030
f2_end
ctor 11, 0x00404030
f2_end
ctor 11, 0x00404030
f2_end
ctor 11, 0x00404030
f2_end
ctor 11, 0x00404030
f2_end
ctor 11, 0x00404030
f2_end
ctor 11, 0x00404030
f2_end
ctor 11, 0x00404030
f2_end
dtor 0x00404030
dtor 0x00404030
dtor 0x00404030
dtor 0x00404030
dtor 0x00404030
dtor 0x00404030
dtor 0x00404030
dtor 0x00404030
dtor 0x00404030
dtor 0x00404030
dtor 0x00404030


— без комментария

А что стандарт на эту ситуацию говорит?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.