1. Друзья, в это тяжёлое и непонятное для всех нас время мы просим вас воздержаться от любых упоминаний политики на форуме, - этим ситуации не поможешь, а только возникнут ненужные ссоры и обиды. Это касается также шуток и юмора на тему конфликта. Пусть войны будут только виртуальными, а политики решают разногласия дипломатическим путём. С уважением, администрация Old-Games.RU.

    Скрыть объявление
  2. Пожалуйста, внимательно прочитайте правила раздела.
  3. Если Вы видите это сообщение, значит, вы ещё не зарегистрировались на нашем форуме.

    Зарегистрируйтесь, если вы хотите принять участие в обсуждениях. Перед регистрацией примите к сведению:
    1. Не регистрируйтесь с никами типа asdfdadhgd, 354621 и тому подобными, не несущими смысловой нагрузки (ник должен быть читаемым!): такие пользователи будут сразу заблокированы!
    2. Не регистрируйте больше одной учётной записи. Если у вас возникли проблемы при регистрации, то вы можете воспользоваться формой обратной связи внизу страницы.
    3. Регистрируйтесь с реально существующими E-mail адресами, иначе вы не сможете завершить регистрацию.
    4. Обязательно ознакомьтесь с правилами поведения на нашем форуме, чтобы избежать дальнейших конфликтов и непонимания.
    С уважением, администрация форума Old-Games.RU
    Скрыть объявление

Кодерский уголок

Тема в разделе "Мастерская", создана пользователем Dimouse, 10 сен 2006.

  1. Dimouse King of Mice

    Dimouse

    Администратор Переводчик

    Регистрация:
    18 апр 2003
    Сообщения:
    35.045
    В соответствии с назначением раздела, в этой теме предполагается обсуждать конкретные вопросы, которые у вас возникают при создании своих программ (в частности - игр), помогать другим, размещать полезные ссылки на статьи и материалы, которые могут пригодиться другим.

    Что здесь не допускается:
    - беспорядочный флуд на всевозможные темы, в том числе общие обсуждения языков программирования без конкретики (карается по статье "флуд и оффтопик" *),
    - разжигания на темы "что лучше, Си или Си++ и чем они отличаются?", "какой язык программирования лучше X или Y?" и т.п. (карается по статье "флейм и участие в холиварах" *),
    - мерение пиписьками в стиле "я лучше программирую" или "ты не умеешь программировать" (карается по статье "оскорбление участников и их взглядов" *).

    Всё это допускается в специально созданной теме "Беседка для программистов или «Бутерброд с кодом».

    * по усмотрению модератора также возможно применение блокировки в данной теме.

    Оригинальное сообщение
     
    Последнее редактирование модератором: 24 ноя 2014
    CY8R4Y нравится это.
  2.  
  3. Steel Rat Stainless

    Steel Rat

    Регистрация:
    28 дек 2006
    Сообщения:
    3.260
    Хм, ну да, тогда надо.
     
  4. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    Дальше идет еще большая дичь:

    extrasidbank.h
    Код:
    class ExtraSidBank : public Bank
    {
    private:
        typedef std::vector<c64sid*> sids_t;
    
        class resetSID
        {
        public:
            void operator() (sids_t::value_type &e) { e->reset(0xf); }
        };
    
    private:
        /**
         * Size of mapping table. Each 32 bytes another SID chip base address
         * can be assigned to.
         */
        static const int MAPPER_SIZE = 8;
    
    private:
        /**
         * SID mapping table.
         * Maps a SID chip base address to a SID
         * or to the underlying bank.
         */
        Bank *mapper[MAPPER_SIZE];
    
        sids_t sids;
    
    private:
        static unsigned int mapperIndex(int address) { return address >> 5 & (MAPPER_SIZE - 1); }
    
    public:
        virtual ~ExtraSidBank() {}
    
        void reset()
        {
            std::for_each(sids.begin(), sids.end(), resetSID());
        }
    
        void resetSIDMapper(Bank *bank)
        {
            for (int i = 0; i < MAPPER_SIZE; i++)
                mapper[i] = bank;
        }
    
        uint8_t peek(uint_least16_t addr)
        {
            return mapper[mapperIndex(addr)]->peek(addr);
        }
    
        void poke(uint_least16_t addr, uint8_t data)
        {
            mapper[mapperIndex(addr)]->poke(addr, data);
        }
    
        /**
         * Set SID emulation.
         *
         * @param s the emulation
         * @param address the address where to put the chip
         */
        void addSID(c64sid *s, int address)
        {
            sids.push_back(s);
            mapper[mapperIndex(address)] = s;
        }
    };
    
    c64.h
    Код:
    
    class c64: private c64env
    {
        ...
    private:
        typedef std::map<int, ExtraSidBank*> sidBankMap_t;
        ...
    
        /// Extra SIDs
        sidBankMap_t extraSidBanks;
    
        ...
    };
    
    c64.cpp
    Код:
           ExtraSidBank *extraSidBank = extraSidBanks.insert(it, sidBankMap_t::value_type(idx, new ExtraSidBank()))->second;
    
    Вот эта последняя строчка и выдает: sidplayfp\c64\c64.cpp(157): Error! E041:col(58) expression for '->' must be pointer to class, struct or union
     
    Последнее редактирование: 10 дек 2014
  5. Steel Rat Stainless

    Steel Rat

    Регистрация:
    28 дек 2006
    Сообщения:
    3.260
    Geryon, #include "extrasidbank.h" имеетя в наличии в c64.cpp? Хотя не то.
    Вообще insert в данном случае возвращает итератор на пару std::pair<int, ExtraSidBank*>, где .first - это int, а .second - это ExtraSidBank*. В каком именно виде итератор - сильно зависит от реализации, там может быть и не указатель.
    Попробуй так - ExtraSidBank *extraSidBank = extraSidBanks.insert(it, sidBankMap_t::value_type(idx, new ExtraSidBank())).second;
     
    Последнее редактирование: 10 дек 2014
  6. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    Нет, но имеется в c64.h, который в свою очередь имеется в c64.cpp, так что дело, видимо, не в этом.

    Кажется, я это победил таким путем:

    было:
    Код:
    ExtraSidBank *extraSidBank = extraSidBanks.insert(it, sidBankMap_t::value_type(idx, new ExtraSidBank()))->second;
    
    стало:
    Код:
    ExtraSidBank *extraSidBank = extraSidBanks.insert(it, sidBankMap_t::value_type(idx, new ExtraSidBank())).first->second;
    
    Экспериментальным путем я выяснил, что тип возвращаемого .insert() объекта следующий:

    Код:
       std::pair<std::map<int, ExtraSidBank*>::iterator,bool>
    
    А автор кода ожидал не bool значение, а ExtraSidBank* - вот я и заменил ->second на .first->second. Остается лишь гадать, то ли в коде ошибка, то я чего-то не понимаю.
     
    Последнее редактирование: 10 дек 2014
  7. Steel Rat Stainless

    Steel Rat

    Регистрация:
    28 дек 2006
    Сообщения:
    3.260
    first - это ключ, а он у нас int, у инта точно нет second. Не знаю, что ты победил. =)
     
  8. Рыжий Тигра Сам себе «пират»

    Рыжий Тигра

    Регистрация:
    3 май 2012
    Сообщения:
    1.823
    ss_temp += sprintf( ss_temp, ........ );
     
  9. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    Я тоже совсем не уверен в своих решениях насчет этой мути, которую вижу впервые, но теперь стало компилироваться. Разве это было бы возможно, если я попытался применить ->second к чему-то, имеющему тип int?
     
  10. Рыжий Тигра Сам себе «пират»

    Рыжий Тигра

    Регистрация:
    3 май 2012
    Сообщения:
    1.823
    Ассоциативность у эл-тов структур - слева направо. Т.е. эквивалент:
    Код:
    [COLOR="DarkRed"][B]([/B][/COLOR] extraSidBanks.insert(it, sidBankMap_t::value_type(.....)).first [B][COLOR="DarkRed"])[/COLOR][/B]->second;


    ---------- Сообщение добавлено в 21:16 ---------- Предыдущее сообщение размещено в 21:14 ----------

    А вообще - интересно, это ж сколько в этой коротенькой строчке будет выполнено new'ов и delete'ов? :-(((((
     
  11. Steel Rat Stainless

    Steel Rat

    Регистрация:
    28 дек 2006
    Сообщения:
    3.260
    Geryon, это называется оверинжинирнг. И это ещё далеко не самый худший образец. Разбей на отдельные операции, чтобы понять как работает, кто что возвращает.
     
  12. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    Собственно, так я и поступил, иначе ни за что не смог бы понять, что откуда растет. На самом деле сейчас код выглядит так:

    Код:
        std::pair<std::map<int, ExtraSidBank*>::iterator,bool> ret;
    
        ...
    
        ret = extraSidBanks.insert(it, sidBankMap_t::value_type(idx, new ExtraSidBank()));
        ExtraSidBank *extraSidBank = ret.first->second;    
    
    И вот новая напасть:

    romCheck.h
    Код:
    class romCheck
    {
    private:
        typedef std::map<std::string, const char*> md5map;
    
    private:
        md5map m_checksums;
    
        ...
    
    private:
        std::string checksum() const
        {
            sidmd5 md5;
            md5.append (m_rom, m_size);
            md5.finish();
    
            return md5.getDigest();
        }
    
        ...
    
    public:
        const char* info() const
        {
            md5map::const_iterator res = m_checksums.find(checksum()); // sidplayfp\romCheck.h(95): Error! E419:col(38) cannot call non-const function for a constant object
            return (res!=m_checksums.end())?res->second:"Unknown Rom";
        }
    };
    
     
    Последнее редактирование: 10 дек 2014
  13. Steel Rat Stainless

    Steel Rat

    Регистрация:
    28 дек 2006
    Сообщения:
    3.260
    Может в старом стандарте было что-то типа find_const? Есди нет, то сделай const char* info() const
     
    Geryon нравится это.
  14. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    Я заглянул во включаемый файл map на предмет чего-то типа find_const, а там:

    Код:
        iterator find(const key_type& k);
        const_terator find(const key_type& x) const;
    
    Исправил const_terator на const_iterator... но ошибка, как ни странно, никуда не исчезла.

    А, ну понятно - там этот код был внутри комментария для справки, а на самом деле никакой const версии нет :cry:

    Это помогло.
     
    Последнее редактирование: 11 дек 2014
  15. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    player.h
    Код:
    
    class Player
    #ifdef PC64_TESTSUITE
      : public testEnv
    #endif
    {
        ...
    public:
        ...
        uint_least32_t time() const { return (uint_least32_t)(m_c64.getEventScheduler().getTime(EVENT_CLOCK_PHI1) / cpuFreq()); }
        ...
    };
    

    player.cpp
    Код:
    const char TXT_NA[]             = "NA";
    
    
    Player::Player () :
        /* Set default settings for system */
        m_tune(0),
        m_errorString(TXT_NA),
        m_isPlaying(false),
        m_rand((unsigned int)::time(0)) // sidplayfp\player.cpp(44): Error! E927: col(28) syntax error: 'time' has not been declared
    {
        ...
    }
    
    Что вообще означает эта запись: Player::Player() : и тут какие-то члены класса пошли со скобками?

    Мало того, что компилятору не нравится запись ::time, так еще и определение Player::time не содержит аргументов, а вызывается с аргументом: time(0)

    При этом у автора кода все отлично компилируется gcc.

    Как такое возможно?
     
    Последнее редактирование: 11 дек 2014
  16. Рыжий Тигра Сам себе «пират»

    Рыжий Тигра

    Регистрация:
    3 май 2012
    Сообщения:
    1.823
    Та ж конструктор же ж.
    Инициализация членов класса
    Это не ф-ция-член класса, это ::time, т.е. вызов функции вне класса. А m_rand инициализируется значением, возвращённым этой функцией.
    Отсутствие пробелов?
     
    Geryon нравится это.
  17. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    Вот оно что! Действительно, включение <time.h> решило проблему (до этого был включен только <ctime>).

    Какое отсутствие пробелов? Я теперь полагаю, что просто у gcc в <ctime> есть функция time, а у OW нет.

    Заглянул в \WATCOM\h\ctime:

    Код:
    namespace std {
    ...
    _WCRTLINK extern time_t       time( time_t *__timer );
    ...
    }
    
    Это что значит? Что есть std::time, а просто time нету?
     
    Последнее редактирование: 11 дек 2014
  18. Steel Rat Stainless

    Steel Rat

    Регистрация:
    28 дек 2006
    Сообщения:
    3.260
    Geryon, всё, что в неймспейсе std, относится к стандартной библиотеке C++. Сделано для разделения от С.
     
  19. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    Хм. Почему этот код может не видеть неймспейса std?
     
  20. Рыжий Тигра Сам себе «пират»

    Рыжий Тигра

    Регистрация:
    3 май 2012
    Сообщения:
    1.823
    Ну, например:
    Код:
    int jx=0,jy=0,jz=jx+++jy;
    - чему будет равен jz?
    Не, ну я не настаиваю. Но вот такая запись
    Код:
    m_rand( (unsigned int) ::time( NULL ) )
    читается не в пример понятнее.
     
    Последнее редактирование: 11 дек 2014
  21. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    Понятия не имею! Трактовать эти +++ можно минимум двумя способами.

    Эта запись на мой взгляд, в отличие от +++, не является многозначной. На всякий случай я расставил пробелы, но ничего не изменилось: пока не включишь <time.h> - не компилируется.
     
  22. Рыжий Тигра Сам себе «пират»

    Рыжий Тигра

    Регистрация:
    3 май 2012
    Сообщения:
    1.823
    (поднимает коготь) Изменилось восприятие "::time()" - теперь видно, что это не член класса, а отдельная функция. Соответственно, разбор ошибок будет идти быстрее.
    А Х его З. В те времена, когда я изучал C++, использование namespace'ов то ли не было обязательным, то ли даже не поощрялось. А было это в аккурат на закате эпохи MS-DOS, чуть меньше 20 лет назад.
     
  1. На этом сайте используются файлы cookie, чтобы персонализировать содержимое, хранить Ваши предпочтения и держать Вас авторизованным в системе, если Вы зарегистрировались.
    Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie.
    Скрыть объявление