static + local var
От: Аноним  
Дата: 07.07.11 16:58
Оценка:
привет
Подскажите в каком случае выгодно добавлять static к временной локальной переменной в функции?
Чтобы она не создавалась каждый раз на стеке(хранить состояние между вызовами не нужно)
c++ static local var
Re: static + local var
От: jyuyjiyuijyu  
Дата: 07.07.11 17:45
Оценка:
Здравствуйте, Аноним, Вы писали:

А>привет

А>Подскажите в каком случае выгодно добавлять static к временной локальной переменной в функции?
А>Чтобы она не создавалась каждый раз на стеке(хранить состояние между вызовами не нужно)
статик внутри функции это всегда непереносимая функция какашка годная только для одного проекта и специфического контекста несовместимая с многопоточностью вообщем это плохо этого надо избегать при любой возможности хорошие мобильные и реентабельные функции не должны обращатся к глобальнывм данным к этому надо стремится в идеале
Re: static + local var
От: purser Россия  
Дата: 07.07.11 18:00
Оценка: :)
Я,к примеру, реализую семантику "заморозки" метода после первого вызова с помощью static.

// Freeze.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <vector>
#include <algorithm>

#define FREEZABLE(ret) static std::vector<void*> __freezeHelper__;\
    std::vector<void*>::iterator result;\
    result = std::find(__freezeHelper__.begin(), __freezeHelper__.end(), this);\
    if (result == __freezeHelper__.end())\
        __freezeHelper__.push_back(this);\
    else return ret


class Temp {
public:
    void f() {
        FREEZABLE(;)
        printf("f for Temp called");
    }
};

int main(int argc, char* argv[])
{
    Temp t1;
    t1.f();//have output
    t1.f();//no effect
    t1.f();//no effect

    Temp t2;
    t2.f();//have output
    t2.f();//no effect
    t2.f();//no effect
    
    return 0;
}




Здравствуйте, Аноним, Вы писали:

А>привет

А>Подскажите в каком случае выгодно добавлять static к временной локальной переменной в функции?
А>Чтобы она не создавалась каждый раз на стеке(хранить состояние между вызовами не нужно)
Re[2]: static + local var
От: igna Россия  
Дата: 07.07.11 18:03
Оценка: 1 (1) +3 :)
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>статик внутри функции это всегда непереносимая функция какашка годная только для одного проекта и специфического контекста несовместимая с многопоточностью


Вот пример не вызывающий вышеуказанных проблем:

void f()
{
    static char const s[] = "abcd";
    . . .
}
Re[2]: static + local var
От: Cyberax Марс  
Дата: 07.07.11 18:10
Оценка: +1
Здравствуйте, purser, Вы писали:

P>Я,к примеру, реализую семантику "заморозки" метода после первого вызова с помощью static.

P>
P>int main(int argc, char* argv[])
P>{
P>    Temp t1;
P>    t1.f();//have output
P>    t1.f();//no effect
P>    t1.f();//no effect

P>    Temp t2;
P>    t2.f();//have output
P>    t2.f();//no effect
P>    t2.f();//no effect
    
P>    return 0;
P>}
P>

Багокод!

int main(int argc, char* argv[])
{
    {
        Temp t1;
        t1.f();//have output
        t1.f();//no effect
        t1.f();//no effect
    }

    {
        Temp t2;
        t2.f();//no effect!?!?! WTF???
    }
    return 0;
}

Если указатели this совпадут случайно.
Sapienti sat!
Re[3]: static + local var
От: purser Россия  
Дата: 07.07.11 18:17
Оценка: :)
Да, косячок...

Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, purser, Вы писали:


P>>Я,к примеру, реализую семантику "заморозки" метода после первого вызова с помощью static.

P>>
P>>int main(int argc, char* argv[])
P>>{
P>>    Temp t1;
P>>    t1.f();//have output
P>>    t1.f();//no effect
P>>    t1.f();//no effect

P>>    Temp t2;
P>>    t2.f();//have output
P>>    t2.f();//no effect
P>>    t2.f();//no effect
    
P>>    return 0;
P>>}
P>>

C>Багокод!

C>
C>int main(int argc, char* argv[])
C>{
C>    {
C>        Temp t1;
C>        t1.f();//have output
C>        t1.f();//no effect
C>        t1.f();//no effect
C>    }

C>    {
C>        Temp t2;
C>        t2.f();//no effect!?!?! WTF???
C>    }
C>    return 0;
C>}
C>

C>Если указатели this совпадут случайно.
Re[3]: static + local var
От: jyuyjiyuijyu  
Дата: 07.07.11 18:20
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, jyuyjiyuijyu, Вы писали:


J>>статик внутри функции это всегда непереносимая функция какашка годная только для одного проекта и специфического контекста несовместимая с многопоточностью


I>Вот пример не вызывающий вышеуказанных проблем:


I>
I>void f()
I>{
I>    static char const s[] = "abcd";
I>    . . .
I>}
I>

я говорю про проблемы при попытке выполнить кукок кода несколько десятков функций
вызывающих друг друга сразу в нескольких потоках если там есть статики то
поимееш геморой и самое простое будет влепить синхронизацию а если бы сразу
писался в расчете на многопоточное выполнение то архитектура была бы другая
Re[3]: static + local var
От: jyuyjiyuijyu  
Дата: 07.07.11 18:27
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, jyuyjiyuijyu, Вы писали:


J>>статик внутри функции это всегда непереносимая функция какашка годная только для одного проекта и специфического контекста несовместимая с многопоточностью


I>Вот пример не вызывающий вышеуказанных проблем:


I>
I>void f()
I>{
I>    static char const s[] = "abcd";
I>    . . .
I>}
I>

получается так что хороший реентабельный код всегда независим а со статиками
очень контекстнозависим м очень специфичен для конкретной проги отношение из
за этого к нему "фуу..."
Re: static + local var
От: Erop Россия  
Дата: 07.07.11 18:28
Оценка: +1 :)))
Здравствуйте, Аноним, Вы писали:

А>Подскажите в каком случае выгодно добавлять static к временной локальной переменной в функции?

А>Чтобы она не создавалась каждый раз на стеке(хранить состояние между вызовами не нужно)

Когда тебе кажется, что тебя завтра уволят без выходного пособия
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: static + local var
От: ДимДимыч Украина http://klug.org.ua
Дата: 07.07.11 18:32
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>несовместимая с многопоточностью


Для многопоточного приложения достаточно обеспечить к такой переменной синхронный доступ, и проблем не будет.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[3]: static + local var
От: jyuyjiyuijyu  
Дата: 07.07.11 18:40
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>Здравствуйте, jyuyjiyuijyu, Вы писали:


J>>несовместимая с многопоточностью


ДД>Для многопоточного приложения достаточно обеспечить к такой переменной синхронный доступ, и проблем не будет.

вот именно обеспечить а если это не твой код и ты в нем в зуб ногой
ну как обеспечиш ? когда разберешся чтоб где то в другом не накосячить
конечно если это твой код то можеш хоть что делать
статик это сплошные грабли ни одного плюса только минусы
Re[2]: static + local var
От: Erop Россия  
Дата: 07.07.11 18:45
Оценка: :)
Здравствуйте, purser, Вы писали:

P>Я,к примеру, реализую семантику "заморозки" метода после первого вызова с помощью static.

А зачем это вообще надо? Кроме того, ТС написал, что ему не надо хранить контекст между вызовами.

P>
P>// Freeze.cpp : Defines the entry point for the console application.
P>//
P>#include "stdafx.h"
P>#include <vector>
P>#include <algorithm>

P>#define FREEZABLE(ret) static std::vector<void*> __freezeHelper__;\
P>    std::vector<void*>::iterator result;\
P>    result = std::find(__freezeHelper__.begin(), __freezeHelper__.end(), this);\
P>    if (result == __freezeHelper__.end())\
P>        __freezeHelper__.push_back(this);\
P>    else return ret


P>


Теперь по этому коду. Тебя не смущает, что
1) Это не читабельно ни разу
2) Это UB
3) Это не работает в обычном случае
4) А в многпоточном окружении это не работает просто фатально
5) Ну и тупо поле с флагом проще, понятнее, эффективнее и надёжнее.

Для просветления советую помедитировать над кодом:
void ups()
{
    Temp t;
    t.f();
}

int main(int argc, char* argv[])
{
    for( int i = 0; i < 10; i++ ) {
        ups();
    }
    return 0;
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: static + local var
От: purser Россия  
Дата: 07.07.11 19:04
Оценка: :)
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, purser, Вы писали:


P>>Я,к примеру, реализую семантику "заморозки" метода после первого вызова с помощью static.

E>А зачем это вообще надо? Кроме того, ТС написал, что ему не надо хранить контекст между вызовами.
Допустим, есть виртуальный метод инициализации. Он должен быть вызван для объекта один раз.
Я знаю, что это ужасно выглядит для макрофобов. Скажи как мне по другому объявить такую семантику.

P>>
P>>// Freeze.cpp : Defines the entry point for the console application.
P>>//
P>>#include "stdafx.h"
P>>#include <vector>
P>>#include <algorithm>

P>>#define FREEZABLE(ret) static std::vector<void*> __freezeHelper__;\
P>>    std::vector<void*>::iterator result;\
P>>    result = std::find(__freezeHelper__.begin(), __freezeHelper__.end(), this);\
P>>    if (result == __freezeHelper__.end())\
P>>        __freezeHelper__.push_back(this);\
P>>    else return ret


P>>


E>Теперь по этому коду. Тебя не смущает, что

E>1) Это не читабельно ни разу
Кому как
E>2) Это UB
С кем не бывает, нужно докрутить, предложения принимаются
E>3) Это не работает в обычном случае
Почему же нет. Можешь проверить.

E>4) А в многпоточном окружении это не работает просто фатально

А мне и не надо в многопоточном.
E>5) Ну и тупо поле с флагом проще, понятнее, эффективнее и надёжнее.
Мне удобней вставить одно слово в функцию, чем заводить флажки и методы для них

E>Для просветления советую помедитировать над кодом:

E>void ups()
E>{
E>    Temp t;
E>    t.f();
E>}

E>int main(int argc, char* argv[])
E>{
E>    for( int i = 0; i < 10; i++ ) {
E>        ups();
E>    }
E>    return 0;
E>}
E>

И что здесь не так?
Re[4]: static + local var
От: Vain Россия google.ru
Дата: 07.07.11 19:28
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>я говорю про проблемы при попытке выполнить кукок кода несколько десятков функций

J>вызывающих друг друга сразу в нескольких потоках если там есть статики то
J>поимееш геморой и самое простое будет влепить синхронизацию а если бы сразу
J>писался в расчете на многопоточное выполнение то архитектура была бы другая
Вы ставите условие с многопоточностью как заведомо не ложное, но забываете что условие ставите не вы.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[4]: static + local var
От: Vain Россия google.ru
Дата: 07.07.11 19:36
Оценка:
Здравствуйте, purser, Вы писали:

E>>4) А в многпоточном окружении это не работает просто фатально

P>А мне и не надо в многопоточном.
E>>5) Ну и тупо поле с флагом проще, понятнее, эффективнее и надёжнее.
P>Мне удобней вставить одно слово в функцию, чем заводить флажки и методы для них
А мне нифига не удобней читать чужой г-код из-за того что кому-то стало неудобно заводить флажки и методы для них. Первое правило программиста — ты пишешь код не для себя! Ты его нарушил — поведение твоих коллег по отношение к тебе — UB! Намёк понятен?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[4]: static + local var
От: Vain Россия google.ru
Дата: 07.07.11 19:40
Оценка: :)
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>>>несовместимая с многопоточностью

ДД>>Для многопоточного приложения достаточно обеспечить к такой переменной синхронный доступ, и проблем не будет.
J>вот именно обеспечить а если это не твой код и ты в нем в зуб ногой
J>ну как обеспечиш ? когда разберешся чтоб где то в другом не накосячить
Стопудовая логика, код не понял — поставлю мютекс.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[5]: static + local var
От: purser Россия  
Дата: 07.07.11 19:46
Оценка:
Здравствуйте, Vain, Вы писали:

V>Здравствуйте, purser, Вы писали:


E>>>4) А в многпоточном окружении это не работает просто фатально

P>>А мне и не надо в многопоточном.
E>>>5) Ну и тупо поле с флагом проще, понятнее, эффективнее и надёжнее.
P>>Мне удобней вставить одно слово в функцию, чем заводить флажки и методы для них
V>А мне нифига не удобней читать чужой г-код из-за того что кому-то стало неудобно заводить флажки и методы для них. Первое правило программиста — ты пишешь код не для себя! Ты его нарушил — поведение твоих коллег по отношение к тебе — UB! Намёк понятен?

Тебе сложно один раз прочитать макрос и понять для чего он ? Ну так и будешь всю жизнь флажки копипастить.
Re[3]: static + local var
От: Cyberax Марс  
Дата: 07.07.11 19:53
Оценка: +1
Здравствуйте, ДимДимыч, Вы писали:

J>>несовместимая с многопоточностью

ДД>Для многопоточного приложения достаточно обеспечить к такой переменной синхронный доступ, и проблем не будет.
Не поможет с реентарабельным кодом.
Sapienti sat!
Re[6]: static + local var
От: Cyberax Марс  
Дата: 07.07.11 19:55
Оценка:
Здравствуйте, purser, Вы писали:

V>>А мне нифига не удобней читать чужой г-код из-за того что кому-то стало неудобно заводить флажки и методы для них. Первое правило программиста — ты пишешь код не для себя! Ты его нарушил — поведение твоих коллег по отношение к тебе — UB! Намёк понятен?

P>Тебе сложно один раз прочитать макрос и понять для чего он ? Ну так и будешь всю жизнь флажки копипастить.
"У каждой проблемы есть простое, красивое и неправильное решение" (с) Генри Менкен
Sapienti sat!
Re[7]: static + local var
От: purser Россия  
Дата: 07.07.11 20:05
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, purser, Вы писали:


V>>>А мне нифига не удобней читать чужой г-код из-за того что кому-то стало неудобно заводить флажки и методы для них. Первое правило программиста — ты пишешь код не для себя! Ты его нарушил — поведение твоих коллег по отношение к тебе — UB! Намёк понятен?

P>>Тебе сложно один раз прочитать макрос и понять для чего он ? Ну так и будешь всю жизнь флажки копипастить.
C>"У каждой проблемы есть простое, красивое и неправильное решение" (с) Генри Менкен

Язык должен позволять создавать новые абстракции, называть их и пользоваться ими. Я просто попытался создать нужную
мне абстракцию на С++.
Re[6]: static + local var
От: dilmah США  
Дата: 07.07.11 20:07
Оценка: +1
P>Тебе сложно один раз прочитать макрос и понять для чего он ? Ну так и будешь всю жизнь флажки копипастить.

мало придумать идею. Нужно придумать 10 идей и выбросить 9.
Re[6]: static + local var
От: Vain Россия google.ru
Дата: 07.07.11 21:24
Оценка: +1
Здравствуйте, purser, Вы писали:

E>>>>4) А в многпоточном окружении это не работает просто фатально

P>>>А мне и не надо в многопоточном.
E>>>>5) Ну и тупо поле с флагом проще, понятнее, эффективнее и надёжнее.
P>>>Мне удобней вставить одно слово в функцию, чем заводить флажки и методы для них
V>>А мне нифига не удобней читать чужой г-код из-за того что кому-то стало неудобно заводить флажки и методы для них. Первое правило программиста — ты пишешь код не для себя! Ты его нарушил — поведение твоих коллег по отношение к тебе — UB! Намёк понятен?
P>Тебе сложно один раз прочитать макрос и понять для чего он ?
Нет, но причём здесь это? Твой макрос нифига не эквивалентен тому же самому флажку, но мало того что убожество, так ещё и баги вносит.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[8]: static + local var
От: Cyberax Марс  
Дата: 07.07.11 22:27
Оценка:
Здравствуйте, purser, Вы писали:

C>>"У каждой проблемы есть простое, красивое и неправильное решение" (с) Генри Менкен

P>Язык должен позволять создавать новые абстракции, называть их и пользоваться ими. Я просто попытался создать нужную
P>мне абстракцию на С++.
В данном случае, проблема не имеет правильного красивого решения (язык С++ ограничен в своей выразительной мощности). Но это не повод использовать неправильное.
Sapienti sat!
Re[4]: static + local var
От: ДимДимыч Украина http://klug.org.ua
Дата: 07.07.11 22:41
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Не поможет с реентарабельным кодом.


Если блокировка не в обработчике сигнала, и в синхронном блоке не вызывать функций, которые могут вызвать эту же функцию рекурсивно, то никаких проблем не должно быть
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[5]: static + local var
От: Erop Россия  
Дата: 08.07.11 05:24
Оценка:
Здравствуйте, Vain, Вы писали:

V>Стопудовая логика, код не понял — поставлю мютекс.


Это называется "привет, привет, гайзенбаг-дедлок!!!"
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: static + local var
От: Erop Россия  
Дата: 08.07.11 05:25
Оценка:
Здравствуйте, purser, Вы писали:

P>Тебе сложно один раз прочитать макрос и понять для чего он ? Ну так и будешь всю жизнь флажки копипастить.

Копипастить будешь не всю жизнь, а пока на С++ программировать не научишься...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: static + local var
От: Erop Россия  
Дата: 08.07.11 05:26
Оценка:
Здравствуйте, Cyberax, Вы писали:

P>>Тебе сложно один раз прочитать макрос и понять для чего он ? Ну так и будешь всю жизнь флажки копипастить.

C>"У каждой проблемы есть простое, красивое и неправильное решение" (с) Генри Менкен

В данном случае, тем не менее, оно НЕпростое и НЕкрасивое. Хотя с "НЕправильным" коллега таки попал
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: static + local var
От: Erop Россия  
Дата: 08.07.11 05:26
Оценка: :)
Здравствуйте, purser, Вы писали:

P>Язык должен позволять создавать новые абстракции, называть их и пользоваться ими. Я просто попытался создать нужную

P>мне абстракцию на С++.

Скорее на С...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: static + local var
От: Socrat Россия  
Дата: 08.07.11 05:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>привет

А>Подскажите в каком случае выгодно добавлять static к временной локальной переменной в функции?
А>Чтобы она не создавалась каждый раз на стеке(хранить состояние между вызовами не нужно)

Контролировать рекурсивность, первый вызов функции...
Re[4]: static + local var
От: Erop Россия  
Дата: 08.07.11 05:31
Оценка: :)
Здравствуйте, purser, Вы писали:

P>>>Я,к примеру, реализую семантику "заморозки" метода после первого вызова с помощью static.

E>>А зачем это вообще надо? Кроме того, ТС написал, что ему не надо хранить контекст между вызовами.
P>Допустим, есть виртуальный метод инициализации. Он должен быть вызван для объекта один раз.
P>Я знаю, что это ужасно выглядит для макрофобов. Скажи как мне по другому объявить такую семантику.

Ну, например, NVI интерфейс инициализации в базе...
class FrozenInit {
public:
    bool Init()
    {
        if( isInited ) {
            return false;
        }
        //  Тут можно добвать поддержку многопоточности, если надо.
        isInited = true;
        DoFrozenInit();
        return true;
    }
protected:
    FrozenInit() : isInited( false ) {}
    FrozenInit( const FrozenInit& ) : isInited( false ) {} // или какая там у тебя семантика?
    void operator = ( const FrozenInit& ) {}

    virtual ~FrozenInit() {}

    virtual void DoFrozenInit() = 0;
private:
    bool isInited;
};

//  Пример использования:
class Test : public FrozenInit {
    void DoFrozenInit();
public:
    //  тут интерфейс класса... если надо, можешь явно упомянуть Init()
};

Если ты придумаешь, зачем иметь несколько "отмороженных" методов, то легко написать CRTP шаблон, который будет хранит много флажков в битиках одного слова...

При этом, обрати внимание, что если объекты не передаются между нитями, то оно сразу MT-ready, надёжно работает, НЕ ТРАТИТ времени на вызов, если он не нужен, ну и на поиски в массивах тоже. Ну и вообще работоспособно, корректно и читабельно.
С++ довольно мощный язык, и свои мысли можно выражать на нём ПРЯМО.

E>>Теперь по этому коду. Тебя не смущает, что

E>>1) Это не читабельно ни разу
P>Кому как
Хочешь -- устрой тут голосовалку
Но, я обращу твоё внимание, что ты показал этот код с багой, которую САМ И НЕ ЗАМЕТИЛ...

E>>2) Это UB

P>С кем не бывает, нужно докрутить, предложения принимаются
Беда в том, что это невозможно докрутить. Да и не нужно.

E>>3) Это не работает в обычном случае

P>Почему же нет. Можешь проверить.
Я привёл тебе пример простого случая, когда оно не работает. Цайберакс привёл другой пример на ту же тему.
Но вот тебе случай повеселее, добавь к своему примеру
static class SuperTemp : public Temp {
public:
    SuperTemp() { f(); }
    ~SuperTemp() { f(); }

} ups_ups;


E>>4) А в многпоточном окружении это не работает просто фатально

P>А мне и не надо в многопоточном.
Беда тут в том, что и читабельность и другие кондиции кода нужны, если код живёт промышленной жизнью, развивается, поддерживается и всё такое. При такой жизни код часто меняет программиста. Ну и вообще часто есть плод коллективных усилий. А при таких делах, легко может внезапно понадобиться MT, и просто забесплатно отказываться от него -- глупо...

E>>5) Ну и тупо поле с флагом проще, понятнее, эффективнее и надёжнее.

P>Мне удобней вставить одно слово в функцию, чем заводить флажки и методы для них
А вариант с базой тебе как?

E>>Для просветления советую помедитировать над кодом:

E>>void ups()
E>>{
E>>    Temp t;
E>>    t.f();
E>>}

E>>int main(int argc, char* argv[])
E>>{
E>>    for( int i = 0; i < 10; i++ ) {
E>>        ups();
E>>    }
E>>    return 0;
E>>}
E>>

P>И что здесь не так?

Ну ты подумай, попробуй исполнить и всё такое...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: static + local var
От: Erop Россия  
Дата: 08.07.11 05:37
Оценка: +2 :)
Здравствуйте, purser, Вы писали:

P>Тебе сложно один раз прочитать макрос и понять для чего он ?

Вообще-то сложно понять, так как у макросов очень плохо формализованы предусловия их использования.
Но часто бывает ещё и другая проблема. В макросах, именно потому, что их трудно понять, часто бывают ошибки, которые, иногда ни разу не ошибки, а хитрые фичи.
Вот твой макрос, например, ни разу не эквивалентен тупому решению с флажком. И вот попал к тебе на рефакторинг/поддержку такой код. И поди пойми, имел в виду автор кода такую семнтику, как написал, такую, как была бы у функции с флажком или какую-то третью...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: static + local var
От: igna Россия  
Дата: 08.07.11 06:08
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>я говорю про проблемы при попытке выполнить кукок кода несколько десятков функций

J>вызывающих друг друга сразу в нескольких потоках если там есть статики то
J>поимееш геморой...

В общем случае это неверно, потому я и привел пример статической локальной переменной, не создающей проблем независимо от того, сколько там десятков или сотен вызывающих друг друга функций и тысяч потоков.
Re[5]: static + local var
От: Erop Россия  
Дата: 08.07.11 06:38
Оценка: :)
Здравствуйте, igna, Вы писали:

I>В общем случае это неверно, потому я и привел пример статической локальной переменной, не создающей проблем независимо от того, сколько там десятков или сотен вызывающих друг друга функций и тысяч потоков.


Формально ты, конечно прав, но на самом деле, это не переменная никакая, а литерал так просто оформлен...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: static + local var
От: purser Россия  
Дата: 08.07.11 07:08
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, purser, Вы писали:


P>>>>Я,к примеру, реализую семантику "заморозки" метода после первого вызова с помощью static.

E>>>А зачем это вообще надо? Кроме того, ТС написал, что ему не надо хранить контекст между вызовами.
P>>Допустим, есть виртуальный метод инициализации. Он должен быть вызван для объекта один раз.
P>>Я знаю, что это ужасно выглядит для макрофобов. Скажи как мне по другому объявить такую семантику.

E>Ну, например, NVI интерфейс инициализации в базе...

E>
class FrozenInit {
E>public:
E>    bool Init()
E>    {
E>        if( isInited ) {
E>            return false;
E>        }
E>        //  Тут можно добвать поддержку многопоточности, если надо.
E>        isInited = true;
E>        DoFrozenInit();
E>        return true;
E>    }
E>protected:
E>    FrozenInit() : isInited( false ) {}
E>    FrozenInit( const FrozenInit& ) : isInited( false ) {} // или какая там у тебя семантика?
E>    void operator = ( const FrozenInit& ) {}

E>    virtual ~FrozenInit() {}

E>    virtual void DoFrozenInit() = 0;
E>private:
E>    bool isInited;
E>};

E>//  Пример использования:
E>class Test : public FrozenInit {
E>    void DoFrozenInit();
E>public:
E>    //  тут интерфейс класса... если надо, можешь явно упомянуть Init()
E>};
E>

E>Если ты придумаешь, зачем иметь несколько "отмороженных" методов, то легко написать CRTP шаблон, который будет хранит много флажков в битиках одного слова...

E>При этом, обрати внимание, что если объекты не передаются между нитями, то оно сразу MT-ready, надёжно работает, НЕ ТРАТИТ времени на вызов, если он не нужен, ну и на поиски в массивах тоже. Ну и вообще работоспособно, корректно и читабельно.

E>С++ довольно мощный язык, и свои мысли можно выражать на нём ПРЯМО.
Вот-вот. И где же ты тут выразил свою мысль прямо ? Допустим, ты пишешь модификатор доступа const в объявлении метода. Одно слово.
И всем сразу понятно, что ты хотел этим сказать. Теперь представь, что нет в плюсах const. Не замучаешься с флажками ?
С++ — ограниченный язык, потому что нельзя сотворить такое:

class SomeClass {
public:
void someFunction() const, frozen, logable, busy {
//logable пишет что-то в лог о входе/выходе в функцию
//busy показывает "песочные часы"
}
};





E>>>Теперь по этому коду. Тебя не смущает, что

E>>>1) Это не читабельно ни разу
P>>Кому как
E>Хочешь -- устрой тут голосовалку
E>Но, я обращу твоё внимание, что ты показал этот код с багой, которую САМ И НЕ ЗАМЕТИЛ...
E>>>2) Это UB
P>>С кем не бывает, нужно докрутить, предложения принимаются
E>Беда в том, что это невозможно докрутить. Да и не нужно.
Думаю, возможно. Будет время, подумаю над этим.


E>>>3) Это не работает в обычном случае

P>>Почему же нет. Можешь проверить.
E>Я привёл тебе пример простого случая, когда оно не работает. Цайберакс привёл другой пример на ту же тему.
E>Но вот тебе случай повеселее, добавь к своему примеру
static class SuperTemp : public Temp {
E>public:
E>    SuperTemp() { f(); }
E>    ~SuperTemp() { f(); }

E>} ups_ups;



E>>>4) А в многпоточном окружении это не работает просто фатально

P>>А мне и не надо в многопоточном.
E>Беда тут в том, что и читабельность и другие кондиции кода нужны, если код живёт промышленной жизнью, развивается, поддерживается и всё такое. При такой жизни код часто меняет программиста. Ну и вообще часто есть плод коллективных усилий. А при таких делах, легко может внезапно понадобиться MT, и просто забесплатно отказываться от него -- глупо...

E>>>5) Ну и тупо поле с флагом проще, понятнее, эффективнее и надёжнее.

P>>Мне удобней вставить одно слово в функцию, чем заводить флажки и методы для них
E>А вариант с базой тебе как?
Не нравится. Многословно.

E>>>Для просветления советую помедитировать над кодом:

E>>>void ups()
E>>>{
E>>>    Temp t;
E>>>    t.f();
E>>>}

E>>>int main(int argc, char* argv[])
E>>>{
E>>>    for( int i = 0; i < 10; i++ ) {
E>>>        ups();
E>>>    }
E>>>    return 0;
E>>>}
E>>>

P>>И что здесь не так?

E>Ну ты подумай, попробуй исполнить и всё такое...

Объект Temp создается на стеке по одному и тому же адресу...Понятно.
У меня в реальной программе немного другое макроопределение. Оно на Qt и выдерживает этот тест.
Пока не буду его приводить.
Re[5]: static + local var
От: jyuyjiyuijyu  
Дата: 08.07.11 07:25
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, jyuyjiyuijyu, Вы писали:


J>>я говорю про проблемы при попытке выполнить кукок кода несколько десятков функций

J>>вызывающих друг друга сразу в нескольких потоках если там есть статики то
J>>поимееш геморой...

I>В общем случае это неверно, потому я и привел пример статической локальной переменной, не создающей проблем независимо от того, сколько там десятков или сотен вызывающих друг друга функций и тысяч потоков.

статик зло и нет ему оправдания
(не рассматривая случаи (как например ваш) когда он only read но это скорее исключение)
а не only read статики даже в заранее предполагаемой однопоточной
среде это связывание по рукам и ногам от распараллеливания
такого кода в будущем а ой как может понадобится хотя раньше и не думал
а чужому программисту распараллелить твой код со статиками полнейший геморой
Re[6]: static + local var
От: igna Россия  
Дата: 08.07.11 09:02
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>статик зло и нет ему оправдания

J>(не рассматривая случаи (как например ваш) когда он only read но это скорее исключение)

Почему это, не рассматривая? И даже если не рассматривая, так ты эту оговорку-то сразу делай, а не заявляй огульно про все "статик внутри функции".

И кстати, read-only не всегда снимает проблему.
Re[6]: static + local var
От: igna Россия  
Дата: 08.07.11 09:06
Оценка: :)
Здравствуйте, Erop, Вы писали:

E>Формально ты, конечно прав, но на самом деле, это не переменная никакая, а литерал так просто оформлен...


"Формально" это и есть единственное, что считается. Мы же про программирование, а не про жизнь и про любовь.
Re[4]: static + local var
От: igna Россия  
Дата: 08.07.11 09:09
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>получается так что хороший реентабельный код всегда независим а со статиками

J>очень контекстнозависим м очень специфичен для конкретной проги отношение из
J>за этого к нему "фуу..."

В смысле, вместо того, чтобы узнать, когда использование статических локальных переменных безопасно, и когда нет, проще наложить на себя обет не использовать их вообще?
Re[5]: static + local var
От: jyuyjiyuijyu  
Дата: 08.07.11 09:26
Оценка:
Здравствуйте, igna, Вы писали:

I>Почему это, не рассматривая? И даже если не рассматривая, так ты эту оговорку-то сразу делай, а не заявляй огульно про все "статик внутри функции".

потому что любой практик а не теоретик понимает что read only не попадало под рассмотрение так как юзается в одном проценте из ста так вам понятней ?
I>И кстати, read-only не всегда снимает проблему.
это вообще не в тему
I>"Формально" это и есть единственное, что считается. Мы же про программирование, а не про жизнь и про любовь.
вы точно теоретик
I>В смысле, вместо того, чтобы узнать, когда использование статических локальных переменных безопасно, и когда нет, проще наложить на себя обет не использовать их вообще?
это вообще полный финиш значит из за 1 процента read only статик перменных вы согласны признать статик не всегда злом и полагаете что это просто от недопонимания

ps если вам хочется потролить то вы мимо
Re[6]: static + local var
От: igna Россия  
Дата: 08.07.11 09:48
Оценка: 1 (1) +1
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>потому что любой практик а не теоретик понимает что read only не попадало под рассмотрение так как юзается в одном проценте из ста так вам понятней ?


Я read-only переменные использую чаще чем не read-only.

J>это вообще не в тему


Это все же где-то в тему, поскольку немаловероятно, что кое-кто думает, что использование read-only static local переменных никогда не ведет к проблемам, к которым ведет использование не read-only static local переменных. А это не так.

J>это вообще полный финиш значит из за 1 процента read only статик перменных вы согласны признать статик не всегда злом и полагаете что это просто от недопонимания


Отнюдь не 1 процент.
Re: static + local var
От: igna Россия  
Дата: 08.07.11 10:38
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Подскажите в каком случае выгодно добавлять static к временной локальной переменной в функции?

А>Чтобы она не создавалась каждый раз на стеке(хранить состояние между вызовами не нужно)

Не совсем ответ на этот вопрос, но вот что написал Matthew Wilson в книге Imperfect C++:

11.3 Function-Local Static Objects

. . .

Imperfection: Function-local static instances of classes with nontrivial constructors are not thread-safe.


Другой проблемный случай рассмотрен в стандарте:

6.7 Declaration statement [stmt.dcl]

. . .

4 . . . If control re-enters the declaration (recursively) while the object is being initialized, the behavior
is undefined. [Example:

int foo(int i)
{
    static int s = foo(2*i); // recursive call – undefined
    return i+1;
}

—end example]

Re: static + local var
От: ДимДимыч Украина http://klug.org.ua
Дата: 08.07.11 11:50
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Подскажите в каком случае выгодно добавлять static к временной локальной переменной в функции?


1. Когда нужно хранить состояние. Например, при кэшировании результатов вычислений.
2. Для объявления read-only констант внутри функции. В случае со static не тратится время на инициализацию констант каждый раз при входе в функцию.
3. В специфичных условиях, когда нужно экономить стек. Например, в микроконтроллерах, если большая глубина вложенности вызовов.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[2]: static + local var
От: BSDыщъх  
Дата: 08.07.11 12:22
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:


А>>привет

А>>Подскажите в каком случае выгодно добавлять static к временной локальной переменной в функции?
А>>Чтобы она не создавалась каждый раз на стеке(хранить состояние между вызовами не нужно)
J>статик внутри функции это всегда непереносимая функция какашка годная только для одного проекта и специфического контекста несовместимая с многопоточностью вообщем это плохо этого надо избегать при любой возможности хорошие мобильные и реентабельные функции не должны обращатся к глобальнывм данным к этому надо стремится в идеале

Про знаки препинания слышал?
Sine vilitate, sine malitiosa mente
Re[7]: static + local var
От: Erop Россия  
Дата: 08.07.11 17:41
Оценка: :)
Здравствуйте, igna, Вы писали:

I>"Формально" это и есть единственное, что считается. Мы же про программирование, а не про жизнь и про любовь.

Главная беда, что это не особо полезно. "формально" тут значит "ничего не даёт по сути", ну почти ничего...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: static + local var
От: Erop Россия  
Дата: 08.07.11 17:49
Оценка:
Здравствуйте, igna, Вы писали:

I>Я read-only переменные использую чаще чем не read-only.

Йо! И они часто static?..
Можно узнать, зачем?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: static + local var
От: Erop Россия  
Дата: 08.07.11 17:58
Оценка:
Здравствуйте, purser, Вы писали:

P>>>Допустим, есть виртуальный метод инициализации. Он должен быть вызван для объекта один раз.

P>>>Я знаю, что это ужасно выглядит для макрофобов. Скажи как мне по другому объявить такую семантику.

E>>Ну, например, NVI интерфейс инициализации в базе...

E>>
class FrozenInit {
E>>public:
E>>    bool Init()
E>>    {
E>>        if( isInited ) {
E>>            return false;
E>>        }
E>>        //  Тут можно добвать поддержку многопоточности, если надо.
E>>        isInited = true;
E>>        DoFrozenInit();
E>>        return true;
E>>    }
E>>protected:
E>>    FrozenInit() : isInited( false ) {}
E>>    FrozenInit( const FrozenInit& ) : isInited( false ) {} // или какая там у тебя семантика?
E>>    void operator = ( const FrozenInit& ) {}

E>>    virtual ~FrozenInit() {}

E>>    virtual void DoFrozenInit() = 0;
E>>private:
E>>    bool isInited;
E>>};

E>>//  Пример использования:
E>>class Test : public FrozenInit {
E>>    void DoFrozenInit();
E>>public:
E>>    //  тут интерфейс класса... если надо, можешь явно упомянуть Init()
E>>};
E>>

E>>Если ты придумаешь, зачем иметь несколько "отмороженных" методов, то легко написать CRTP шаблон, который будет хранит много флажков в битиках одного слова...

E>>При этом, обрати внимание, что если объекты не передаются между нитями, то оно сразу MT-ready, надёжно работает, НЕ ТРАТИТ времени на вызов, если он не нужен, ну и на поиски в массивах тоже. Ну и вообще работоспособно, корректно и читабельно.

E>>С++ довольно мощный язык, и свои мысли можно выражать на нём ПРЯМО.
P>Вот-вот. И где же ты тут выразил свою мысль прямо ? Допустим, ты пишешь модификатор доступа const в объявлении метода. Одно слово.
P>И всем сразу понятно, что ты хотел этим сказать. Теперь представь, что нет в плюсах const. Не замучаешься с флажками ?
Вообще не будет флажков. Будет два интерфейса к классу. Для r\o доступа и для полного.

P>С++ — ограниченный язык, потому что нельзя сотворить такое:


P>
P>class SomeClass {
P>public:
P>void someFunction() const, frozen, logable, busy {
P>//logable пишет что-то в лог о входе/выходе в функцию
P>//busy показывает "песочные часы"
P>}
P>};
P>

Это будет какой-то другой язык.
Ты, кстати, так тоже не смог.
Но в С++ такого рода свойства принято выражать наследованием.
Типа class SomeClass : public FrozenInit {
virtual void DoFrozenInit() { ... }
};

E>>Хочешь -- устрой тут голосовалку

E>>Но, я обращу твоё внимание, что ты показал этот код с багой, которую САМ И НЕ ЗАМЕТИЛ...
Так голосовалку ты устроил, или и так признал, что твой вариант нечитабельный?

E>>>>2) Это UB

P>Думаю, возможно. Будет время, подумаю над этим.
Тут есть такая беда, что надо как-то умирающие объекты вымарывать из списка. При этом даже умершие без вызова деструктора...

E>>Но вот тебе случай повеселее, добавь к своему примеру
static class SuperTemp : public Temp {
E>>public:
E>>    SuperTemp() { f(); }
E>>    ~SuperTemp() { f(); }

E>>} ups_ups;

Так ты проверил, что получается с таким кодом-то?

E>>>>5) Ну и тупо поле с флагом проще, понятнее, эффективнее и надёжнее.

P>>>Мне удобней вставить одно слово в функцию, чем заводить флажки и методы для них
E>>А вариант с базой тебе как?
P>Не нравится. Многословно.
Что многословно? Идея "запускать один раз на один объект" там выражена прямо. Код простой, клиентский код минимальный...

P>>>И что здесь не так?

E>>Ну ты подумай, попробуй исполнить и всё такое...
P>Объект Temp создается на стеке по одному и тому же адресу...Понятно.
P>У меня в реальной программе немного другое макроопределение. Оно на Qt и выдерживает этот тест.
P>Пока не буду его приводить.
Что-то, как-то верится с трудом...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: static + local var
От: purser Россия  
Дата: 08.07.11 20:13
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, purser, Вы писали:


P>>>>Допустим, есть виртуальный метод инициализации. Он должен быть вызван для объекта один раз.

P>>>>Я знаю, что это ужасно выглядит для макрофобов. Скажи как мне по другому объявить такую семантику.

E>>>Ну, например, NVI интерфейс инициализации в базе...

E>>>
class FrozenInit {
E>>>public:
E>>>    bool Init()
E>>>    {
E>>>        if( isInited ) {
E>>>            return false;
E>>>        }
E>>>        //  Тут можно добвать поддержку многопоточности, если надо.
E>>>        isInited = true;
E>>>        DoFrozenInit();
E>>>        return true;
E>>>    }
E>>>protected:
E>>>    FrozenInit() : isInited( false ) {}
E>>>    FrozenInit( const FrozenInit& ) : isInited( false ) {} // или какая там у тебя семантика?
E>>>    void operator = ( const FrozenInit& ) {}

E>>>    virtual ~FrozenInit() {}

E>>>    virtual void DoFrozenInit() = 0;
E>>>private:
E>>>    bool isInited;
E>>>};

E>>>//  Пример использования:
E>>>class Test : public FrozenInit {
E>>>    void DoFrozenInit();
E>>>public:
E>>>    //  тут интерфейс класса... если надо, можешь явно упомянуть Init()
E>>>};
E>>>

E>>>Если ты придумаешь, зачем иметь несколько "отмороженных" методов, то легко написать CRTP шаблон, который будет хранит много флажков в битиках одного слова...

E>>>При этом, обрати внимание, что если объекты не передаются между нитями, то оно сразу MT-ready, надёжно работает, НЕ ТРАТИТ времени на вызов, если он не нужен, ну и на поиски в массивах тоже. Ну и вообще работоспособно, корректно и читабельно.

E>>>С++ довольно мощный язык, и свои мысли можно выражать на нём ПРЯМО.
P>>Вот-вот. И где же ты тут выразил свою мысль прямо ? Допустим, ты пишешь модификатор доступа const в объявлении метода. Одно слово.
P>>И всем сразу понятно, что ты хотел этим сказать. Теперь представь, что нет в плюсах const. Не замучаешься с флажками ?
E>Вообще не будет флажков. Будет два интерфейса к классу. Для r\o доступа и для полного.
Это как ?

P>>С++ — ограниченный язык, потому что нельзя сотворить такое:


P>>
P>>class SomeClass {
P>>public:
P>>void someFunction() const, frozen, logable, busy {
P>>//logable пишет что-то в лог о входе/выходе в функцию
P>>//busy показывает "песочные часы"
P>>}
P>>};
P>>

E> Это будет какой-то другой язык.
E>Ты, кстати, так тоже не смог.
E>Но в С++ такого рода свойства принято выражать наследованием.
E>Типа class SomeClass : public FrozenInit {
E> virtual void DoFrozenInit() { ... }
E>};
Если мне произвольный метод произвольного класса нужно "заморозить", как тут наследование поможет?

E>>>Хочешь -- устрой тут голосовалку

E>>>Но, я обращу твоё внимание, что ты показал этот код с багой, которую САМ И НЕ ЗАМЕТИЛ...
E>Так голосовалку ты устроил, или и так признал, что твой вариант нечитабельный?
То что бажный, признаю. Но нечитабельный скорее твой вариант.
E>>>>>2) Это UB
P>>Думаю, возможно. Будет время, подумаю над этим.
E>Тут есть такая беда, что надо как-то умирающие объекты вымарывать из списка. При этом даже умершие без вызова деструктора...

E>>>Но вот тебе случай повеселее, добавь к своему примеру
static class SuperTemp : public Temp {
E>>>public:
E>>>    SuperTemp() { f(); }
E>>>    ~SuperTemp() { f(); }

E>>>} ups_ups;

E>Так ты проверил, что получается с таким кодом-то?
Ладно, верю)

E>>>>>5) Ну и тупо поле с флагом проще, понятнее, эффективнее и надёжнее.

P>>>>Мне удобней вставить одно слово в функцию, чем заводить флажки и методы для них
E>>>А вариант с базой тебе как?
P>>Не нравится. Многословно.
E>Что многословно? Идея "запускать один раз на один объект" там выражена прямо. Код простой, клиентский код минимальный...
Это же каждый раз надо такое писать. Я хочу идею "заморозки" зафиксировать одним словом. В определении или лучше в объявлении.

P>>>>И что здесь не так?

E>>>Ну ты подумай, попробуй исполнить и всё такое...
P>>Объект Temp создается на стеке по одному и тому же адресу...Понятно.
P>>У меня в реальной программе немного другое макроопределение. Оно на Qt и выдерживает этот тест.
P>>Пока не буду его приводить.
E>Что-то, как-то верится с трудом...
Re[8]: static + local var
От: igna Россия  
Дата: 08.07.11 20:14
Оценка: 1 (1)
Здравствуйте, Erop, Вы писали:

E>Йо! И они часто static?..

E>Можно узнать, зачем?

Можно. Статические переменные как и переменные вообще у меня чаще read-only чем не read-only. Или ты юродствуешь просто?
Re[9]: static + local var
От: Erop Россия  
Дата: 09.07.11 00:33
Оценка:
Здравствуйте, igna, Вы писали:

E>>Йо! И они часто static?..

E>>Можно узнать, зачем?

I>Можно. Статические переменные как и переменные вообще у меня чаще read-only чем не read-only. Или ты юродствуешь просто?


Это не ответ на вопрос "зачем".
Вопрос же конкретный стоит, про static in function, которые сами по себе редко нужны.
Зачем константы, объявленные в функции делать статическими? Пример какой-нибудь кода, можешь привести?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: static + local var
От: Erop Россия  
Дата: 09.07.11 00:54
Оценка:
Здравствуйте, purser, Вы писали:

E>>>>Если ты придумаешь, зачем иметь несколько "отмороженных" методов, то легко написать CRTP шаблон, который будет хранит много флажков в битиках одного слова...


E>>Вообще не будет флажков. Будет два интерфейса к классу. Для r\o доступа и для полного.

P>Это как ?

Ну посмотри на std::list<int>::iterator и std::list<int>::const_iterator, например.
На самом деле, новации -- это хорошо, но чтобы новации были хорошими, лучше сначала изучить язык, и уже накопленный опыт.

E>>Но в С++ такого рода свойства принято выражать наследованием.

E>>Типа class SomeClass : public FrozenInit {
E>> virtual void DoFrozenInit() { ... }
E>>};
P>Если мне произвольный метод произвольного класса нужно "заморозить", как тут наследование поможет?

Ты вот оставил очень большой рверквотинг, которого тут очень не любят, но так и не прочитал его внимательно при этом. Я же писал тебе, что через CRTP-шаблон удобно будет сделать. Только мне не понятна сама по себе идея "заморозить" произвольный метод произвольного класса. Зачем это вообще надо-то?
Я не случайно спрашиваю "зачем надо", потому, что для всех сколько-нибудь реально востребованных сценариев в С++ уже давно что-то предложено. Либо есть одно хорошее, либо есть есть много с ограничениями всякими. Но какие-то варианты, кроме "индусского копи-паста" есть всегда. Поэтому поясни юзкейс, а я или кто-то ещё из тутошних завсегдатаев попробуем предложить вариант решения.

P> То что бажный, признаю. Но нечитабельный скорее твой вариант.

Ну так устрой голосовалку. "Нечетабельный" -- это очень просто. Это если берёшь 100 прогеров средней квалификации, которые не в теме задачи, но знают язык и стандартный инструментарий и смотрим процент прогеров, который разберётся за минуту на кило кода, например, или среднее время и т. д.
В общем суть в том, что нечетабельный код сильно сопротивляется усилиям посторонних вникнуть. Обычно это сильно мешает поддержке.
Так что, если ты считаешь, что твои макросы с точкой с запятой в качестве параметра читабельны, то устрой таки голосовалку.
Хорошим признаком читабельности было бы такое решение, что прочитав клиентский код не возникло бы желания лезть в определение макроса...

P>Ладно, верю)

В общем, как ни жаль, но подход плох по многим направлениям. Хранить флаг в объекте метода намного прямее, чем в статическом ассациативном контейнере...

P>Это же каждый раз надо такое писать. Я хочу идею "заморозки" зафиксировать одним словом. В определении или лучше в объявлении.


А зачем базу писать много раз? Её можно переиспользовать.
Ну, в конце концов, если ты так любишь макросы, то пока не разлюбил, можешь написать макрос, определяющий такую базу, например. Но надёжнее сделать не макрос, а шаблон, наверное.
Но, перед тем, как делать, хорошо бы понять цель. Так как не совсем понятно, что надо сделать. Например, если у метода есть возвращаемое значение, то что он должен вернуть, когда он уже заморозился?..

P>>>У меня в реальной программе немного другое макроопределение. Оно на Qt и выдерживает этот тест.

P>>>Пока не буду его приводить.
E>>Что-то, как-то верится с трудом...

Так как у тебя решается проблема создания разных объектов по одинаковым адресам-то?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: static + local var
От: igna Россия  
Дата: 09.07.11 06:47
Оценка: 12 (1)
Здравствуйте, Erop, Вы писали:

E>Зачем константы, объявленные в функции делать статическими? Пример какой-нибудь кода, можешь привести?


Так я же привел уже. Ну вот еще:

    static struct {
        char chr;
        char const* ref;
    } const char_ref[] = {
        { '<', "lt" },
        { '>', "gt" },
        { '&', "amp" },
        { '\'', "apos" },
        { '"', "quot" },
    };


Даже если и без слова static компилятор сможет соптимизировать инициализацию (сможет ли?), static еще и читающему программу говорит, что значение char_ref является общим для всех вызовов функции, в которой char_ref объявлена. (Слова const недостаточно, поскольку в списке инициализации могли быть использованы параметры или глобальные переменные.)
Re[11]: static + local var
От: SleepyDrago Украина  
Дата: 09.07.11 09:48
Оценка: +1
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Erop, Вы писали:


E>>Зачем константы, объявленные в функции делать статическими? Пример какой-нибудь кода, можешь привести?


I>Так я же привел уже. Ну вот еще:


I>
I>    static struct {
I>        char chr;
I>        char const* ref;
I>    } const char_ref[] = {
I>        { '<', "lt" },
I>        { '>', "gt" },
I>        { '&', "amp" },
I>        { '\'', "apos" },
I>        { '"', "quot" },
I>    };
I>


Зачем тебе отложенная инициализация этой таблички? и мьютекс впридачу. Место все равно выделяется там же где и глобальные. Я бы на ревью зарубил.
Re[8]: static + local var
От: blackhearted Украина  
Дата: 09.07.11 10:06
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, igna, Вы писали:


I>>"Формально" это и есть единственное, что считается. Мы же про программирование, а не про жизнь и про любовь.

E>Главная беда, что это не особо полезно. "формально" тут значит "ничего не даёт по сути", ну почти ничего...
вот как раз почти иногда и нужно.
Re[6]: static + local var
От: blackhearted Украина  
Дата: 09.07.11 10:07
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>Здравствуйте, igna, Вы писали:


I>>Здравствуйте, jyuyjiyuijyu, Вы писали:


J>>>я говорю про проблемы при попытке выполнить кукок кода несколько десятков функций

J>>>вызывающих друг друга сразу в нескольких потоках если там есть статики то
J>>>поимееш геморой...

I>>В общем случае это неверно, потому я и привел пример статической локальной переменной, не создающей проблем независимо от того, сколько там десятков или сотен вызывающих друг друга функций и тысяч потоков.

J>статик зло и нет ему оправдания
J>(не рассматривая случаи (как например ваш) когда он only read но это скорее исключение)
J>а не only read статики даже в заранее предполагаемой однопоточной
J>среде это связывание по рукам и ногам от распараллеливания
а если код не будет параллелиться? т.е. вообще не будет.
J>такого кода в будущем а ой как может понадобится хотя раньше и не думал
wtf ?
J>а чужому программисту распараллелить твой код со статиками полнейший геморой
беда-беда
Re[12]: static + local var
От: igna Россия  
Дата: 09.07.11 16:51
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

SD>Зачем тебе отложенная инициализация этой таблички? и мьютекс впридачу.


Мне они не нужны, в данном случае компилятор вправе применить статическую инициализацию.
Re[13]: static + local var
От: Erop Россия  
Дата: 09.07.11 20:54
Оценка:
Здравствуйте, igna, Вы писали:

I>Мне они не нужны, в данном случае компилятор вправе применить статическую инициализацию.

Ну, это тот же пример, что и первый. Ты создаёшь некую предопределённую константную структуру в памяти, фактически литерал, но в коде функции пердставляешь её, как static in function константу, а не как-то ещё, попроще.
Ну вычурно записал простую вещь. Но смысл так извращаться от меня ускользает. А другие какие-нибудь примеры есть?
Или это всегда наследники COMMON DATA из FORTRAN?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[14]: static + local var
От: igna Россия  
Дата: 10.07.11 07:19
Оценка:
Здравствуйте, Erop, Вы писали:

E>Ну, это тот же пример, что и первый. Ты создаёшь некую предопределённую константную структуру в памяти, фактически литерал, но в коде функции пердставляешь её, как static in function константу, а не как-то ещё, попроще.

E>Ну вычурно записал простую вещь. Но смысл так извращаться от меня ускользает.

Где вычурность-то, в добавлении static? Смысл очевидно в сужении области видимости. Константы (как и функции, и типы) вовсе не обязательно объявлять как можно локальнее, иногда константу лучше сделать глобальной, даже если используется она в одном единственном месте, но иногда — нет. Для этого последнего случая можно воспользоваться static внутри функции или даже блока.

E>А другие какие-нибудь примеры есть? Или это всегда наследники COMMON DATA из FORTRAN?


Я других не знаю. Тем не менее заявления вроде "статик внутри функции это всегда непереносимая функция какашка" как бы относятся и к приведенным мной примерам, и скорые на расправу рубщики рубят ведь "на ревью", и локальные по сути константы болтаются потом в глобальной области видимости или еще где.
Re[9]: static + local var
От: purser Россия  
Дата: 10.07.11 08:40
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, purser, Вы писали:


E>>>>>Если ты придумаешь, зачем иметь несколько "отмороженных" методов, то легко написать CRTP шаблон, который будет хранит много флажков в битиках одного слова...


E>>>Вообще не будет флажков. Будет два интерфейса к классу. Для r\o доступа и для полного.

P>>Это как ?

E>Ну посмотри на std::list<int>::iterator и std::list<int>::const_iterator, например.

E>На самом деле, новации -- это хорошо, но чтобы новации были хорошими, лучше сначала изучить язык, и уже накопленный опыт.
Но мне же нужен один метод, который должен быть константным. А что должен делать неконстантный его брат-близнец и зачем он нужен?


E>>>Но в С++ такого рода свойства принято выражать наследованием.

E>>>Типа class SomeClass : public FrozenInit {
E>>> virtual void DoFrozenInit() { ... }
E>>>};
P>>Если мне произвольный метод произвольного класса нужно "заморозить", как тут наследование поможет?

E>Ты вот оставил очень большой рверквотинг, которого тут очень не любят, но так и не прочитал его внимательно при этом. Я же писал тебе, что через CRTP-шаблон удобно будет сделать. Только мне не понятна сама по себе идея "заморозить" произвольный метод произвольного класса. Зачем это вообще надо-то?

E>Я не случайно спрашиваю "зачем надо", потому, что для всех сколько-нибудь реально востребованных сценариев в С++ уже давно что-то предложено. Либо есть одно хорошее, либо есть есть много с ограничениями всякими. Но какие-то варианты, кроме "индусского копи-паста" есть всегда. Поэтому поясни юзкейс, а я или кто-то ещё из тутошних завсегдатаев попробуем предложить вариант решения.

class Condom {
public:
enum {Xxl, Tiny}
bool use() enable_only_calls(1);
};
//...
Condom* xxl= CondomsCollection.get(Condom::Xxl);
if (xxl) {
xxl->use();
trash->utilize(xxl);
//bla-bla-bla
} else {
xxl= trash->get(Condom::Xxl);//
if (xxl) {
xxl->use(); //compile time (or run-time) error 'attempt to call frozen use() method'
}
}



Или, например:
class User {
public:
bool login() enable_only_calls(3);
};
//...
try {
while (!user->login())
user->getPassword();
}
catch(Exception &e) {
//only 3 attempts for login !!!
}

//Сравни с этим
for (int i=0; i<user.maxCountOfLoginAttempts(); ++i)
if (!user->login())
user->getPassword();
if (!user.logined())
return;

Ну и на кой мне тут сдалась переменная-индекс цикла ? Она меня вообще не интересует, но я вынужден её таки использовать.
Ещё метод maxCountOfLoginAttempts() дополнительно нужно заводить.

В Ruby ,например, можно "заморозить" весь объект
freeze (Ruby)

E>А зачем базу писать много раз? Её можно переиспользовать.

E>Ну, в конце концов, если ты так любишь макросы, то пока не разлюбил, можешь написать макрос, определяющий такую базу, например. Но надёжнее сделать не макрос, а шаблон, наверное.
E>Но, перед тем, как делать, хорошо бы понять цель. Так как не совсем понятно, что надо сделать. Например, если у метода есть возвращаемое значение, то что он должен вернуть, когда он уже заморозился?..
Default value

E>Так как у тебя решается проблема создания разных объектов по одинаковым адресам-то?..

Пока сам не разобрался. Разберусь — устрою голосовалку)
Re[15]: static + local var
От: jyuyjiyuijyu  
Дата: 10.07.11 15:44
Оценка: 3 (1)
Здравствуйте, igna, Вы писали:

I>Я других не знаю. Тем не менее заявления вроде "статик внутри функции это всегда непереносимая функция какашка" как бы относятся и к приведенным мной примерам, и скорые на расправу рубщики рубят ведь "на ревью", и локальные по сути константы болтаются потом в глобальной области видимости или еще где.




нда какой же вы интересный человек вцепились в этот 1 процент юз кейса в качестве
статических констант
и не видите 99 процентов говна со статиками у меня очень редко статическая пермеменная в коде
я фактически сразу думаю о многопоточности и почти их не использую
а вот намного чаще пытался распараллелить свой и чужой код со статиками и приходилось
переделывать потому что писался он в расчете на однопоточное исполнение а мне нужно было его
параллельно запускать и сейчас часто вижу код со статиками инвалидный в многопоточной среде
а этот код выкладывают как примеры нате мол пользуйтесь а вы говорите статик хорошо
это костыли за очень редким исключением
даже ваш пример
static struct {
        char chr;
        char const *ref;
    } const char_ref[] = {
        { '<', "lt" },
        { '>', "gt" },
        { '&', "amp" },
        { '\'', "apos" },
        { '"', "quot" },
    };

чуть изменить и этот кусок и уже юзает флажок инвалидный в многопотоке
и что еще хуже C генерирует другой код там можно инитить только
константами и литералами и инититятся они до входа в main все статики а C++
флажки втыкает когда ему вздумается это уже огромный мотив чтоб не пользоватся
этим даже для инита const static переменных вот этот код будучи скомпилен
для C и для C++ на одном компиляторе cl.exe 15.0 генрирует разный код для C
генерируется потокобезопасный а для C++ инвалидный
static struct {
        char chr;
        char const ref[32];
    } const char_ref[] = {
        { '<', "lt" },
        { '>', "gt" },
        { '&', "amp" },
        { '\'', "apos" },
        { '"', "quot" },
    };

каким вы правилои руководствуетесь в этих двух примерах почему один инициализируется
в compile time а второй в run time ? фактически по стандарту C++ они оба инвалидны
там грится что при первом проходе локальный статик инится что фатально
в многопотоке а то что он примитивы в компайл там заинитил (первый пример) так это только
фича компилятора фактически же если не оптимизирует то два раза будет инициализироватся
этот костыль одноврмененно двумя потоками что тут хорошего если даже нет уверенности
когда он данные будет инитить и сколько раз и несовместим с C на базовом уровне
таком как инициализация массива литералами это же полный ахтунг
Re[13]: static + local var
От: Alexey F  
Дата: 10.07.11 16:49
Оценка:
Здравствуйте, igna, Вы писали:

SD>>Зачем тебе отложенная инициализация этой таблички? и мьютекс впридачу.


I>Мне они не нужны, в данном случае компилятор вправе применить статическую инициализацию.

Жаль, конечно, что компилятору только дозволено сделать так, но его никто не обязывает:

4 The zero-initialization (8.5) of all local objects with static storage duration (3.7.1) is performed before any
other initialization takes place. A local object of POD type (3.9) with static storage duration initialized with
constant-expressions is initialized before its block is first entered
. An implementation is permitted to perform
early initialization of other local objects with static storage duration under the same conditions that an
implementation is permitted to statically initialize an object with static storage duration in namespace scope
(3.6.2)
. Otherwise such an object is initialized the first time control passes through its declaration; such an
object is considered initialized upon the completion of its initialization.
[...]

Вполне может попасться какая-нибудь зараза из компиляторов, которая подложит свинью и навернёт многопоточный код
Придётся загаживать глобальное пространство имён единицы трансляции или ещё как-нибудь выкручиваться.
P.S. Нашёлся такой топик давнишний: здесь
Автор:
Дата: 04.11.04
(см. ответ Mr. None
Автор: Mr. None
Дата: 05.11.04
).
Re[15]: static + local var
От: Erop Россия  
Дата: 10.07.11 18:07
Оценка:
Здравствуйте, igna, Вы писали:

I>Я других не знаю. Тем не менее заявления вроде "статик внутри функции это всегда непереносимая функция какашка" как бы относятся и к приведенным мной примерам, и скорые на расправу рубщики рубят ведь "на ревью", и локальные по сути константы болтаются потом в глобальной области видимости или еще где.


Про такие я согласен. Хотя лично мне ближе такие константы объявлять просто статическими, а не статическими в функции.
И надёжнее, и понятнее и от причуд компилятора и платформы меньше зависимость...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: static + local var
От: Erop Россия  
Дата: 10.07.11 18:20
Оценка:
Здравствуйте, purser, Вы писали:

P>Но мне же нужен один метод, который должен быть константным. А что должен делать неконстантный его брат-близнец и зачем он нужен?


Мне так кажется, что ты плохо понимаешь, что такое "константный метод"...

База даёт доступ только к константному интерфейсу. Наследник -- к полному. Если объект ограничен в доступе -- работаешь через указатель/ссылку базу, если нет -- через указатель ссылку на наследника...

E>>Так как у тебя решается проблема создания разных объектов по одинаковым адресам-то?..

P>Пока сам не разобрался. Разберусь — устрою голосовалку)

О! Вот на -- ЧИТАБЕЛЬНОСТЬ!!!
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[14]: static + local var
От: igna Россия  
Дата: 11.07.11 05:57
Оценка: +1 :)
Здравствуйте, Alexey F, Вы писали:


AF>Вполне может попасться какая-нибудь зараза из компиляторов, которая подложит свинью и навернёт многопоточный код

AF>Придётся загаживать глобальное пространство имён единицы трансляции или ещё как-нибудь выкручиваться.

Придется. Но делать это с самого начала и есть та самая преждевременная оптимизация.
Re[16]: static + local var
От: igna Россия  
Дата: 11.07.11 09:33
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

>нда какой же вы интересный человек вцепились в этот 1 процент юз кейса в качестве

J>статических констант
J>и не видите 99 процентов говна со статиками у меня очень редко статическая пермеменная в коде

У меня этот "юз кейс" не 1, а как раз 99% (если не 100) использования static локально.

J>вот этот код будучи скомпилен

J>для C и для C++ на одном компиляторе cl.exe 15.0 генрирует разный код для C
J>генерируется потокобезопасный а для C++ инвалидный
J>static struct {
J>        char chr;
J>        char const ref[32];
J>    } const char_ref[] = {
J>        { '<', "lt" },
J>        { '>', "gt" },
J>        { '&', "amp" },
J>        { '\'', "apos" },
J>        { '"', "quot" },
J>    };


1. Это по-видимому баг VC++.
2. Это только "a performance issue", поскольку если константу 100 раз проинициализировать одним и тем же значением, никаких других проблем ожидать не приходится.
3. Даже и на этот баг я вряд ли наступил бы, покольку обычно перечитываю, что пишу, и заметил бы, что char const* ref заменять надо на char ref[32], а не на char const ref[32], поскольку оставленный тобой при преобразовании кода const имеет в твоем коде совсем другое значение нежели в моем.

J>фактически по стандарту C++ они оба инвалидны

J>там грится что при первом проходе локальный статик инится

Не при, а до: "before its block is first entered".
Re[17]: static + local var
От: Erop Россия  
Дата: 11.07.11 13:38
Оценка:
Здравствуйте, igna, Вы писали:

I>У меня этот "юз кейс" не 1, а как раз 99% (если не 100) использования static локально.

Так это же хорошо!
Не понятно только, зачем и эти 99% не превратить в просто static в единице трансляции, ну да это уже, скорее, вкусовщина, на самом деле.
Главный косяк static in function -- там можно случайно "заморозить" контекст первого вызова функции. Ну да это довольно редкая ошибка, скорее всего.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[18]: static + local var
От: igna Россия  
Дата: 11.07.11 14:06
Оценка:
Здравствуйте, Erop, Вы писали:

E>Не понятно только, зачем и эти 99% не превратить в просто static в единице трансляции, ну да это уже, скорее, вкусовщина, на самом деле.


Во.

И нечего кое-кому (неважно кто это был, хотя это был jyuyjiyuijyu) обзывать это дело какашкой, а кое-кому другому (SleepyDrago) рубить не разобравшись на ревью. Раз вкусовщина.
Re[19]: static + local var
От: Erop Россия  
Дата: 11.07.11 15:08
Оценка: 1 (1)
Здравствуйте, igna, Вы писали:

I>И нечего кое-кому (неважно кто это был, хотя это был jyuyjiyuijyu) обзывать это дело какашкой, а кое-кому другому (SleepyDrago) рубить не разобравшись на ревью. Раз вкусовщина.


По моему опыту "вкусовщина" значит, что не важно как делать, главное, чтобы одинаково.
Так что я вполне понимаю людей, которые договорились так не делать, так как преимуществ это никаких не даёт. Я даже пойму людей, которые сильно ограничат использование static in function в принципе.

IMHO, это примерно такой же "важный" вопрос, как стиль расстановки скобок
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[20]: static + local var
От: igna Россия  
Дата: 12.07.11 05:50
Оценка:
Здравствуйте, Erop, Вы писали:

E>По моему опыту "вкусовщина" значит, что не важно как делать, главное, чтобы одинаково.


Ну естественно.

E>Так что я вполне понимаю людей, которые договорились так не делать, так как преимуществ это никаких не даёт. Я даже пойму людей, которые сильно ограничат использование static in function в принципе.


Ради бога. Только у себя в проекте, а не в публичном форуме.

E>IMHO, это примерно такой же "важный" вопрос, как стиль расстановки скобок


Да, только кавычки я бы убрал, стиль расстановки скобок как и стиль объявлений важны без кавычек, поскольку читабельность.
Re[15]: C++0x => static constexpr
От: Alexey F  
Дата: 13.07.11 08:55
Оценка: 9 (1) +1
Здравствуйте, igna, Вы писали:

Я вдруг вспомнил, что в новом стандарте есть решение без закладывания на implementation-defined: возможность получить выражение, гарантированно вычисляемое на этапе компиляции... :
void func() {
...
    static struct {
        char chr;
        char ref[ 32 ];
    } constexpr char_ref[] = {
        { '<', "lt" },
        { '>', "gt" },
        { '&', "amp" },
        { '\'', "apos" },
        { '"', "quot" }
    };
...
    static char constexpr string[] = "abcdefghijklmnopqrstuvwxyz";
...
}

В сочетании static + constexpr компилятор не занимается созданием массивов на стеке (в отличие от просто constexpr) и, насколько я знаю (а как иначе с constexpr variable-то?), не имеет права отложить инициализацию этого участка.

g++ 4.6.1 (prerelease) не генерирует лишнего кода на этих участках ни без оптимизации, ни после неё. А попытка сломать выражение, сделав его неконстантным, обламывается.

И это даже не преждевременная оптимизация, а контракт на полную константность выражения и уменьшение области видимости
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.