Решено: C++ список инициалиции

Модератор: Модераторы разделов

SpiritFire
Сообщения: 3

Решено: C++ список инициалиции

Сообщение SpiritFire »

Подсткажите, пожалуйста, то ли я чего-то не понимаю, то ли GCC 4.3 под 64-битную Debian работает неправильно... Неправильно - это конечно слишком громко, но не соответствует стандарту.
Суть проблемы есть такой код:

Код: Выделить всё

CPipedFactorialCalculator::CPipedFactorialCalculator(unsigned int x, const CBaseLog& logger)
 : m_pipe        ()
 , m_initialValue(x)
 , m_logger      ( logger.createCopy() )
 , m_pid         ( fork() )
{
   ...
}


Зачем считать факториал в отдельном потоке - потому, что того требует задание на лабу. То же и с пайпами. Я думаю, должно быть так:
1. создается объект пайп,
2. создается объект initialValue
3. создается объект логгер
4. создается объект пид - в этот момент происходит "раздвоение на два процесса"
5. обрабатываются остальные члены класса, не указанные в списке инициализатора.

На самом же деле сначала "раздваивается на два процесса", и лишь затем обрабатывается список инициализатора.

Объясните, пожалуйста, ошибаюсь ли я, или неплохо баг репорт наваять, все-таки незаметный подводный камень.
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: Решено: C++ список инициалиции

Сообщение RasenHerz »

Значения функций, возвращаемых в список инициализации, вычисляются до начала инициализации элементов (т.е. вызов m_pid(fork()) расладывается на pid_t __temp_pid = fork(); m_pid(__temp_pid;). Чтобы все работало так как вы хотите, надо использовать язык подерживающий lazy evaluations.
Спасибо сказали:
SpiritFire
Сообщения: 3

Re: Решено: C++ список инициалиции

Сообщение SpiritFire »

RasenHerz писал(а):
17.09.2009 01:09
Значения функций, возвращаемых в список инициализации, вычисляются до начала инициализации элементов (т.е. вызов m_pid(fork()) расладывается на pid_t __temp_pid = fork(); m_pid(__temp_pid;). Чтобы все работало так как вы хотите, надо использовать язык подерживающий lazy evaluations.


то, что оно вычисляется до инициализации всех элементов, а не до инициализации конкретного элемента (чего можно было бы ожидать) - это я сообразил, вопрос в том, как правильно с точки зрения С++.

А простейшее решение задачи -- как два пальца обасфальт: просто форк в тело конструктора внести... Вопрос не в этом :)
Спасибо сказали:
SpiritFire
Сообщения: 3

Re: Решено: C++ список инициалиции

Сообщение SpiritFire »

Вопрос решён, все проще:

Код: Выделить всё

class CBaseLog;


class CPipedFactorialCalculator          // управляет взаимодействием процессов
{
    typedef auto_ptr<CBaseLog> TLoggerPtr;

public:
    CPipedFactorialCalculator (unsigned int x, const CBaseLog& logger);
    ~CPipedFactorialCalculator();

    double getResult();
    bool   setResult(double result);

private:
    pid_t        m_pid;
    CPipe        m_pipe;
    unsigned int m_initialValue;
    TLoggerPtr   m_logger;


    bool         isChild          ()    {return m_pid == 0;}
    bool         isValid          ()    {return m_pid !=-1;}
    bool         calculate        ();
};


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

Кстати. если включить опцию -Wall, то компилятор заботливо предупредит:

Код: Выделить всё

child.h: In constructor ‘CPipedFactorialCalculator::CPipedFactorialCalculator(unsigned int, const CBaseLog&)’:
child.h:29: предупреждение: ‘CPipedFactorialCalculator::m_pipe’ будет инициализирован после
child.h:28: предупреждение:   ‘pid_t CPipedFactorialCalculator::m_pid’
child.cpp:14: предупреждение:   when initialized here


ЗЫ. Включил бы волл -- секономил бы часа два своего времени...
Спасибо сказали: