На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
  
> Переход из 32 бит к 64. , В программе много переменных типа int и size_t. При переходе к 64 битам int не меняется, а size_t меняется.
    В версии 32 бита int - 4 байта, size_t тоже 4 байта, но при переходе к 64 битам, int остается 4 байта, а size_t становится 8 байт. Возникает много предупреждений при преобразовании типов. Чтобы int стало 8 байт, надо использовать тип __int64. Править текст программы 200 файлов не хотелось бы. Существует ли способ решения этой задачи?
      using ind_t = size_t

      Везде заменить size_t на ind_t (только случайно не заменить выше указанную строчку).
      Все проверить, потом сделать так:
      using ind_t = int

      Я везде использую ind_t (чтоб потом, если что, скорректировать)
      А int/int64 (и типы других размеров) только там, где точно нужен именно 4/8 байт (например в union).
        При работе с vector:

        ExpandedWrap disabled
          vector<...>  V;
          V.size(); //  возвращает в 64-битном варианте size_t 8 байт. Вот с этим то и возникают проблемы.


        И есть другие функции, возвращающие 8-ми байтовый результат в 64-битной версии.
          Все меняйте на size_t
          Другие типы используйте только там, где есть зависимость для длины типа.

          А вот при использовании OpenMP, в циклах тип должен быть знаковым..., вот у меня так:
          ExpandedWrap disabled
            #ifdef _WIN64
            using omp_t = __int64;
            #else
            using omp_t = int;
            #endif
            using ind_t = size_t;


          Добавлено
          А с учетом использования AVX, еще вот такое удобство сделал:
          ExpandedWrap disabled
            #define _REAL_TYPE_
             
            #ifdef _REAL_TYPE_
            using real_t = double;
            #else
            using real_t = float;
            #endif // _REAL_TYPE_


          ExpandedWrap disabled
            void myMatrixFMA::Add_Mul_Matrix(ind_t inPos, const myMatrix &inM1, const myMatrix &inM2, ind_t inCol)
            {
                for (ind_t k = 0; k < inM2.m_Size_Y; ++k)
                {
                    const auto &m0 = inM1.m_Array[k];
            #ifdef _REAL_TYPE_
                    __m256d *_target = (__m256d *) (m_Array[inPos]);
                    __m256d *_source = (__m256d *) (m0);
                    const real_t &inD = inM2.m_Array[inCol][k];
                    const __m256d _d = _mm256_set1_pd(inD);
                    for (ind_t indY = 0; indY < indSum4; ++indY)
                    {
                        *_target = _mm256_fmadd_pd(*(_source++), _d, *_target);
                        ++_target;
                    } // for
            #else
                    __m256 *_target = (__m256 *) (m_Array[inPos]);
                    __m256 *_source = (__m256 *) (m0);
                    const real_t &inD = inM2.m_Array[inCol][k];
                    const __m256 _d = _mm256_set1_ps(inD);
                    for (ind_t indY = 0; indY < indSum2; ++indY)
                    {
                        *_target = _mm256_fmadd_ps(*(_source++), _d, *_target);
                        ++_target;
                    } // if
            #endif // _REAL_TYPE_
                    for (ind_t indY = roundSize2; indY < m_Size_Y; ++indY)
                        m_Array[inPos][indY] += m0[indY] * inD;
                } // for
            }
            Цитата a_n_y_a @
            Править текст программы 200 файлов не хотелось бы. Существует ли способ решения этой задачи?

            Существуют программы для массового изменения файлов.
            Например, TextReplacer.
            Не обязательно корректировать тип переменных.
            Там, где это допустимо, можно применить преобразования типов.
            Чтобы не было проблемы "200 файлов", надо создавать
            проект с двумя сборками. И возникающие проблемы решать сразу.
              Спасибо, работает. Мне в 32 битном приложении, при получении длины файла типа ULONGLONG, надо работать с выделенным буфером по NEW, который принимает переменную типа UINT. И надо проверить не превышает ли длина файла максимально возможной длины буфера. Для этого есть константа INT_MAX. Но эта константа соответствует только 32-х битному проекту. Для 64 бит, эта константа остается той же. Существуют ранги для типов переменных, но хотелось бы работать с виндузовыми константами. Ты знаешь что-нибудь про это?

              Добавлено
              Цитата ЫукпШ @
              Цитата a_n_y_a @
              Править текст программы 200 файлов не хотелось бы. Существует ли способ решения этой задачи?

              Существуют программы для массового изменения файлов.
              Например, TextReplacer.

              В среде VC++ 2017 года есть в меню такая же функция. Вопрос перехода с 32 на 64 возник недавно, вот я и спрашиваю. Пока изучаю вопрос. Спасибо за внимание ко мне.
                new принимает size_t. Откуда вообще взялась проблема с несоответствием типов? Тип объекта однозначно определяет его свойства. Разные типы – разные свойства. Любой каст означает смену свойств объекта. Иногда это надо, но хороший вопрос – как так получилось, что программе такое требуется постоянно?
                  Цитата Qraizer @
                  Откуда вообще взялась проблема с несоответствием типов?

                  Есть переменная int A; Переменная может принимать отрицательное значение, и ей присваивается значение количества элементов в векторе:

                  ExpandedWrap disabled
                    vector<...>  V;
                    A=V.size();

                  Вот тут и проблема, преобразования size_t (unsigned int) в int. У них разные диапазоны. Я написал функцию преобразования size_t в int:
                  ExpandedWrap disabled
                    int IzSIZE_T__to__int(size_t R)
                    {
                        if (R > INT_MAX)
                        {
                            CMyThrowSize_t__to__int th;
                            throw(th);
                            return(-1);
                        }
                        else
                        {
                            return((int)R);
                        };
                    };

                  и
                  ExpandedWrap disabled
                    class CMyThrowSize_t__to__int:public std::exception
                    {
                    public:
                        CMyThrowSize_t__to__int() {};
                        ~CMyThrowSize_t__to__int() {};
                    };

                  Проверял в тестовом проекте, функция работает, исключение создается и обрабатывается. Но у меня рабочий проект MDI, вызов throw происходит в просмотре. В каком месте текста программы (класса) надо написать блок try{}? Что-то я не пойму.
                    Цитата a_n_y_a @
                    Переменная может принимать отрицательное значение, и ей присваивается значение количества элементов в векторе:
                    Ещё раз спросить? Ок.
                    1. Почему переменной, хранящей размер, позволяется иметь отрицательные значения?
                    2. Почему программа имеет десятки, если не сотни, подобных странных проектных решений?
                      Переменную int A я привел для примера. В проекте переменная А работает в алгоритме, и в некоторых случаях ей присваивается значение количества элементов в векторе. Но в других ветках алгоритма, этой переменной присваивается -1, и это значение имеет конкретный смысл.
                      По поводу преобразования size_t в int. Эта проблема шире, чем я описал. Например такой код:
                      ExpandedWrap disabled
                        ...::OnPaint()
                        {
                        ...
                            CRect r;
                            GetClientRect(r);
                            vector <CPoint> mp;
                            mp.push_back(CPoint(r.left, r.top)); mp.push_back(CPoint(r.right, r.top));
                            mp.push_back(CPoint(r.right, r.bottom)); mp.push_back(CPoint(r.left, r.bottom));
                            mp.push_back(CPoint(r.left, r.top));
                                dc.Polyline(&(mp[0]), IzSIZE_T__to__int(mp.size()));
                        ...
                        };

                      Функция Polyline принимает в параметрах количество элементов массива типа int. Чтобы не создавать массив типа
                      ExpandedWrap disabled
                        CPoint mp[3];

                      И не указывать количество элементов массива числом, я работаю с вектором. Конечно можно было бы написать:
                      ExpandedWrap disabled
                        dc.Polyline(&(mp[0]), (int)mp.size());

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

                      Почему программа имеет десятки, если не сотни, подобных странных проектных решений? - Все дело в том, что программа разрабатывалась много лет. Это не коммерческая программа. Сейчас я чищу в программе все слабые места. С функцией преобразования size_t в int программа будет более защищенной. Просто раньше я использовал вариант (int)mp.size(). Теперь решил написать IzSIZE_T__to__int(mp.size()).
                        Цитата a_n_y_a @
                        В проекте переменная А работает в алгоритме, и в некоторых случаях ей присваивается значение количества элементов в векторе.

                        А в других случаях что?

                        Такое ощущение, что одна и та же переменная в памяти, используется в разных местах для разных целей.
                          Походу это некий признак ошибки. Ну, да, часто возникает навязчивое желание не делать статус операции отдельным атрибутом, а как-нибудь замешать в inside boundary уже имеющегося атрибута. Проблемы, когда это невозможно, неизбежны.

                          Добавлено
                          P.S. Не стоит никогда так проектировать логику кода. Недаром практически во всех code style standard присутствует правило, запрещающее использование одной и той же переменной для различных целей. Хранить размер и одновременно признак ошибки как раз такой случай. Ну и никогда не следует смешивать типы данных по назначению. Какие свойства сущности нужны, вот такой тип данных и используем. Размер – значит size_t. Символ-байт – значит char. Число-байт – значит signed char. Итп.
                          Но вообще проблема шире. У меня вот, только что глянул, есть проект на 120к кода. При переносе с 32-х бит на 64 проблема возникла только в двух аспектах, и обе были связаны с изменившимся inside boundary range для size_t. Один из-за DWORD в использовавшихся функциях и структурах Win32, второй из-за 32-битности MS Office SDK, принимающего int через VARIANT. Проблема была решена путём написанного на коленке простенького safe_cast<> в точечных местах, общим числом в пять штук. Никаких десятков предупреждений и массового рефакторинга.
                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                          0 пользователей:


                          Рейтинг@Mail.ru
                          [ Script execution time: 0,0394 ]   [ 16 queries used ]   [ Generated: 29.03.24, 12:34 GMT ]