На главную Наши проекты:
Журнал   ·   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
  
> Непонятный Warning , и непонятная секция
    При компиляции, после не понятно чего ставли появлятся варнинги и ненужная секция в файле

    LIBCMT.lib(mathfcns.obj) : warning LNK4210: .CRT section exists; there may be unhandled static initializers or terminators

    LIBCMT.lib(cpu_disp.obj) : warning LNK4210: .CRT section exists; there may be unhandled static initializers or terminators


    и секция .crt, как это можно убрать? в секции .crt нету ничего нужного:
    ExpandedWrap disabled
      29A04000: B0 21                          MOV AL,21
      29A04002: A0 29                          MOV AL,[00000029]
      29A04004: 74 22                          JZ 29A04028
      29A04006: A0 29                          MOV AL,[00000029]
      29A04008: 00 00                          ADD [EAX],AL
      29A0400A: 00 00                          ADD [EAX],AL


    и ADD [EAX],AL (т.е. симв. #0) идёт ещё много раз...
      Цитата MSDN
      Some code introduced static initializers or terminators, but the CRT or its equivalent (which needs to run the static initializers or terminators) isn't run when the application starts. Examples of code that would cause this:

      Global class variable with a constructor, destructor, or virtual function table.

      Global variable initialized with a non-compile-time constant.

      To fix this problem, do one of the following:

      Remove all code with static initializers.

      Do not use /NOENTRY. After you remove /NOENTRY, you may also have to add msvcrt.lib, libcmt.lib, or libcmtd.lib to your linker command line.

      Add msvcrt.lib, libcmt.lib, or libcmtd.lib to your linker command line.

      If your project is built with /ENTRY, and if /ENTRY is passed a function other than _DllMainCRTStartup, the function must call CRT_INIT.
        а что такое code with static initializers?

        Добавлено
        Ну пример что это такое,чтобы я знал что удалять/изменять?
          Написано ведь:
          Цитата
          Global class variable with a constructor, destructor, or virtual function table.

          Global variable initialized with a non-compile-time constant.


          ExpandedWrap disabled
            static int x = f();
            static SomeClassWithCtorOrDtorOrVTable obj;
            ни одного static'a в проекте нету, а всё равно этот хренов crt, чё делать?
              Цитата rmf @
              ни одного static'a в проекте нету, а всё равно этот хренов crt, чё делать?

              Ну, а то же самое, только на глобальном уровне (не в функциях)?
              ExpandedWrap disabled
                int x = f();
                SomeClassWithCtorOrDtorOrVTable obj;
                Кароче, искал я такие места в программе, не нашел ничего подозрительного, немного подумав, ввел строчку
                ExpandedWrap disabled
                  #pragma comment(linker, "/MERGE:.CRT=.text")

                и помогло! исчези и варнинги, и секция .crt, и размер файла уменьшился на пол кило!
                  Ты убрал одно из следствий (варнинг), а не причину самого варнинга.
                  Вот тебе пример:
                  ExpandedWrap disabled
                    #include <windows.h>
                    #pragma comment(linker, "/ENTRY:main")
                     
                    //#pragma comment(linker, "/MERGE:.CRT=.text")
                     
                    #pragma inline_depth(0)
                    const char* f()
                    {
                        return "abc";
                    }
                    const char* g_psz = f();
                    int main()
                    {  
                        DWORD n;
                        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), g_psz, 3, &n, 0);
                    }

                  При раскомментировании прагмы варнинг пропадает, однако программа от этого не начинает работать правильно.
                  Я не гарантирую 100%, что ты столкнешься с проблемами, однако сам я не видел .crt-секций, которые можно было бы просто игнорировать без последствий.
                    честно говоря не очень понимаю...
                    значит у меня могут быть ошибки, и программа может вылетиеть?

                    а что в этом коде не так?
                      Цитата rmf @
                      значит у меня могут быть ошибки, и программа может вылетиеть?

                      Именно это я и хотел сказать.

                      Цитата
                      а что в этом коде не так?

                      А ты скомпильни и запусти ;)
                      Раз ты тут не видишь, то возможно, что и у себя что-то мог пропустить...
                        Ок, примерно понял в чём проблема...
                        в строке char* g_psz = f();
                        т.е. если при объявлении присваивать то ничего не получается, а если в коде то все ок, а как можно исправить эту ошибку? просто в коде присваивать?
                          Цитата rmf @
                          Ок, примерно понял в чём проблема...
                          в строке char* g_psz = f();
                          т.е. если при объявлении присваивать то ничего не получается

                          Да, но не всё. Происшедшее называется динамической инициализацией (в отличие от статической, когда значение может быть посчитано на этапе компиляции/линковки и просто записано в область памяти переменной, например: char* g_psz = "abc";)
                          Грубо говоря, в данной секции и содержатся указания стартовому коду (который я отключил через /ENTRY) выполнить функцию f() и её результат присвоить переменной g_psz. Лишь после всех инициализаций стартовый код зовет main().
                          Аналогично - с вызовами конструкторов глобальных объектов.
                            Я на си перешел не давно(с delphi), нужно один проект переписать с Делфи на Си, и не очень всё понимаю.

                            Насчет динамической и статической вроде немного понял. Но опять же ничего у себя в коде не нашел :(
                            в msdn'е написанно(ну и ты выше написал, не обратил внимания сначала) что можно добавить библиотеку msvcrt.lib если используешь свою точку входа, и тоже исчезнет вся эта фигня, добавил, исчезла, и даж размер уменьшился вдвое ( 11 kb -> 5.5 kb ), но опять добавился этот msvcrt80.dll(опять пришел к тому, с чего начинал).
                            в списках вызываемых ф-ций есть memcpy, memset, strstr, strchr.

                            1 - добавление библиотеки решит проблему с возможной ошибкой у меня в коде?

                            2 - memcpy, memset, strstr, strchr занимают аж целых почти 6 килобайт?

                            3 - Есть аналоги в апи для этих ф-ций? для ф-ций типа strcpy нашел lstrcpyA и т.д., для этих чета не видел!

                            4 - и после замены этих ф-ций, размер останется таким какой стал? 5.5 кило, и исчезнет ли msvcrt80.dll


                            з.ы. совсем запутался сэтим vs c++
                              Цитата rmf @
                              1 - добавление библиотеки решит проблему с возможной ошибкой у меня в коде?

                              Нет. Её решит только отказ от /ENTRY или нахождение и удаление того, что провоцирует появление секции .crt

                              Цитата
                              2 - memcpy, memset, strstr, strchr занимают аж целых почти 6 килобайт?

                              Не только они. Там еще много всякой всячины.

                              Цитата
                              3 - Есть аналоги в апи для этих ф-ций? для ф-ций типа strcpy нашел lstrcpyA и т.д., для этих чета не видел!

                              memset - FillMemory, memcpy - CopyMemory, memmove - MoveMemory
                              strchr, strstr сам напиши или вырежи из исходников CRT

                              Цитата
                              4 - и после замены этих ф-ций, размер останется таким какой стал? 5.5 кило,

                              Не думаю.

                              Цитата
                              и исчезнет ли msvcrt80.dll

                              Наверное, только после опции компилера /NODEFAULTLIB

                              Цитата
                              з.ы. совсем запутался сэтим vs c++

                              Сам себе геморрой и ищешь.... 6к жалко. Офигеть...
                                Цитата
                                Сам себе геморрой и ищешь.... 6к жалко. Офигеть...

                                Мда... наверное ты прав, но на си я перехожу из-за маленького размера, хочется пользоватся этой возможностью по полной!

                                Цитата

                                Цитата
                                4 - и после замены этих ф-ций, размер останется таким какой стал? 5.5 кило,


                                Не думаю.

                                6 кило, кода > 500 строчек!, это мне кажется оочень хороший результат!

                                но блин, из списка вызываемых библиотек, и ф-ций исчез только strstr и strrchr!!! хотя заменил все ф-ции! в чем может быть дело? :( (memcpy и memsetостались, хотя ниоткуда не вызываются!)
                                Сообщение отредактировано: rmf -
                                  Цитата rmf @
                                  Цитата
                                  Сам себе геморрой и ищешь.... 6к жалко. Офигеть...

                                  Мда... наверное ты прав, но на си я перехожу из-за маленького размера, хочется пользоватся этой возможностью по полной!

                                  Переходи на ассемблер - там всего будет по-полной...

                                  Цитата
                                  но блин, из списка вызываемых библиотек, и ф-ций исчез только strstr!!! хотя заменил все ф-ции! в чем может быть дело? :(

                                  Значит, кто-то продолжает их юзать. /NODEFAULLIB применял?
                                    и на асме пробовал, далье программ типа вызова нескольких апи не решился пойти, решил на си остановится!

                                    угу, получаю
                                    myprj.obj : error LNK2001: unresolved external symbol _memcpy
                                    myprj.obj : error LNK2001: unresolved external symbol _memset

                                    Цитата
                                    Значит, кто-то продолжает их юзать.

                                    Кто? в коде нету их вызова!
                                    Сообщение отредактировано: rmf -
                                      Цитата rmf @
                                      Цитата
                                      Значит, кто-то продолжает их юзать.

                                      Кто? в коде нету их вызова!

                                      Компилятор. Вполне может memset вставить на безобидную конструкцию вроде int a[1000] = { 0 };
                                      Выход - напиши свою функцию memset и memcpy, чтобы он не волновался
                                        Хм.. вот это я сглупил, точно, можно было создать ф-ции с этми именами,
                                        но вот ещё что случилось :)
                                        теперь показывает ошибку

                                        .\myprj.cpp(129) : error C3861: 'memset': identifier not found
                                        на строку FillMemory(recvbuffer,1024,0);
                                        (ну и на другие тоже, где используются эти ф-ции)

                                        ну и как это объяснить? memset использует FillMemory, или наоборот?

                                        в Delphi IDE если нажать на Ctrl и мышкой на имя ф-ции, то показывается где она объявленна и её код, в VS такое можно?

                                        Добавлено
                                        ой, и ещё ошибки:

                                        \myfunc.cpp(13) : error C2169: 'memcpy' : intrinsic function, cannot be defined
                                        \myfunc.cpp(18) : error C2169: 'memset' : intrinsic function, cannot be defined
                                        Сообщение отредактировано: rmf -
                                          Цитата rmf @
                                          ну и как это объяснить? memset использует FillMemory, или наоборот?

                                          FillMemory - это макрос, и раскрывающийся в memset (совсем дырявая голова стала :( ). Вообщем, напиши целиком свои функции, благо это несложно.

                                          Цитата
                                          в Delphi IDE если нажать на Ctrl и мышкой на имя ф-ции, то показывается где она объявленна и её код, в VS такое можно?

                                          Правая кнопка - "Go To Definition"
                                          Цитата

                                          \myfunc.cpp(13) : error C2169: 'memcpy' : intrinsic function, cannot be defined
                                          \myfunc.cpp(18) : error C2169: 'memset' : intrinsic function, cannot be defined


                                          Попробуй написать:
                                          ExpandedWrap disabled
                                            #pragma function(memset, memcpy)
                                          Сообщение отредактировано: Hryak -
                                            #pragma function(memset, memcpy), угу, 2 ошибки ичесли, а что она делает?

                                            FillMemory - это макрос, и раскрывающийся в memset
                                            т.е. FillMemory это не замена memset, а всего лишь вызов memset, и надо написать свой аналог memset? правильно понял?
                                              Цитата rmf @
                                              #pragma function(memset, memcpy), угу, 2 ошибки ичесли, а что она делает?

                                              Это указание компилятору не пытаться использовать встраиваемые версии данных фукнций.

                                              Цитата
                                              т.е. FillMemory это не замена memset, а всего лишь вызов memset, и надо написать свой аналог memset? правильно понял?

                                              Да.
                                                Используй RtlFillMemory и иже с ним из kernel32.lib. Тока на одноименные макросы не нарвись :)

                                                Добавлено
                                                Нечто вроде
                                                ExpandedWrap disabled
                                                  #ifdef RtlFillMemory
                                                  #undef RtlFillMemory
                                                  #endif
                                                  extern "C" NTSYSAPI VOID NTAPI RtlFillMemory ( VOID UNALIGNED *Destination,
                                                      SIZE_T Length,
                                                      IN BYTE  Fill
                                                      );
                                                   
                                                      char ss[10];
                                                      RtlFillMemory(ss,10,0x22);
                                                Сообщение отредактировано: Adil -
                                                  Ну а как сделать? пишу что то типа

                                                  ExpandedWrap disabled
                                                    void *memset( void *dest, int i, size_t count )
                                                    {
                                                        void *dst;
                                                        RtlFillMemory(dst,count,i);
                                                        return dst;
                                                    }


                                                  а он пишет warning C4717: 'memset' : recursive on all control paths, function will cause runtime stack overflow

                                                  и что это значит? опять эта ф-ция использует memset? Как полностью замениить memset (ну и memcpy)?
                                                    Цитата rmf @
                                                    Как полностью замениить memset (ну и memcpy)?

                                                    Ну напиши сам-то.
                                                    ExpandedWrap disabled
                                                      /***
                                                      *char *memset(dst, val, count) - sets "count" bytes at "dst" to "val"
                                                      *
                                                      *Purpose:
                                                      *       Sets the first "count" bytes of the memory starting
                                                      *       at "dst" to the character value "val".
                                                      *
                                                      *Entry:
                                                      *       void *dst - pointer to memory to fill with val
                                                      *       int val   - value to put in dst bytes
                                                      *       size_t count - number of bytes of dst to fill
                                                      *
                                                      *Exit:
                                                      *       returns dst, with filled bytes
                                                      *
                                                      *Exceptions:
                                                      *
                                                      *******************************************************************************/
                                                       
                                                      void * __cdecl memset (
                                                              void *dst,
                                                              int val,
                                                              size_t count
                                                              )
                                                      {
                                                              void *start = dst;
                                                       
                                                      #if defined (_M_IA64) || defined (_M_AMD64)
                                                       
                                                              {
                                                       
                                                       
                                                              __declspec(dllimport)
                                                       
                                                       
                                                              void RtlFillMemory( void *, size_t count, char );
                                                       
                                                              RtlFillMemory( dst, count, (char)val );
                                                       
                                                              }
                                                       
                                                      #else  /* defined (_M_IA64) || defined (_M_AMD64) */
                                                              while (count--) {
                                                                      *(char *)dst = (char)val;
                                                                      dst = (char *)dst + 1;
                                                              }
                                                      #endif  /* defined (_M_IA64) || defined (_M_AMD64) */
                                                       
                                                              return(start);
                                                      }
                                                       
                                                      /***
                                                      *memcpy - Copy source buffer to destination buffer
                                                      *
                                                      *Purpose:
                                                      *       memcpy() copies a source memory buffer to a destination memory buffer.
                                                      *       This routine does NOT recognize overlapping buffers, and thus can lead
                                                      *       to propogation.
                                                      *
                                                      *       For cases where propogation must be avoided, memmove() must be used.
                                                      *
                                                      *Entry:
                                                      *       void *dst = pointer to destination buffer
                                                      *       const void *src = pointer to source buffer
                                                      *       size_t count = number of bytes to copy
                                                      *
                                                      *Exit:
                                                      *       Returns a pointer to the destination buffer
                                                      *
                                                      *Exceptions:
                                                      *******************************************************************************/
                                                       
                                                      void * __cdecl memcpy (
                                                              void * dst,
                                                              const void * src,
                                                              size_t count
                                                              )
                                                      {
                                                              void * ret = dst;
                                                       
                                                      #if defined (_M_IA64)
                                                       
                                                              {
                                                       
                                                       
                                                              __declspec(dllimport)
                                                       
                                                       
                                                              void RtlCopyMemory( void *, const void *, size_t count );
                                                       
                                                              RtlCopyMemory( dst, src, count );
                                                       
                                                              }
                                                       
                                                      #else  /* defined (_M_IA64) */
                                                              /*
                                                               * copy from lower addresses to higher addresses
                                                               */
                                                              while (count--) {
                                                                      *(char *)dst = *(char *)src;
                                                                      dst = (char *)dst + 1;
                                                                      src = (char *)src + 1;
                                                              }
                                                      #endif  /* defined (_M_IA64) */
                                                       
                                                              return(ret);
                                                      }
                                                    Copyright © Microsoft Corporation. All rights reserved.
                                                      Ну дык еслибы знал бы, написал бы!
                                                      (яж говорю, я с Delphi, и особо не понимаю, смысл этого- выделение, осовобождение памяти, и т.д. Как там легко сделать str1:=str1+str2+'hello', а здесь... ф-ции вызывать)

                                                      Ты где этот код взял(дай пожалуйста и на strrchr и strstr, а то я свои версии сделал, но не уверен что они безглючные, и лучше MS'овских)? На Go To Defenition другое совсем!

                                                      Добавлено
                                                      З.Ы. пасибо большое, столько времени потратил на меня!
                                                      Сообщение отредактировано: rmf -
                                                        Всё, спасибо, нашел сам!
                                                        C:\Program Files\Visual Studio 8\VC\crt\src
                                                        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                        0 пользователей:


                                                        Рейтинг@Mail.ru
                                                        [ Script execution time: 0.1115 ]   [ 16 queries used ]   [ Generated: 1.07.26, 12:50 GMT ]