Непонятный Warning
, и непонятная секция
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.217.58] |
|
|
Правила раздела Visual C++ / MFC / WTL (далее Раздела)
FAQ Раздела
Обновления для FAQ Раздела
Поиск по Разделу
MSDN Library Online
Непонятный 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 нету ничего нужного: ![]() ![]() 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) идёт ещё много раз... |
|
Сообщ.
#2
,
|
|
|
|
Цитата 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. |
|
Сообщ.
#3
,
|
|
|
|
а что такое code with static initializers?
Добавлено Ну пример что это такое,чтобы я знал что удалять/изменять? |
|
Сообщ.
#4
,
|
|
|
|
Написано ведь:
Цитата Global class variable with a constructor, destructor, or virtual function table. Global variable initialized with a non-compile-time constant. ![]() ![]() static int x = f(); static SomeClassWithCtorOrDtorOrVTable obj; |
|
Сообщ.
#5
,
|
|
|
|
ни одного static'a в проекте нету, а всё равно этот хренов crt, чё делать?
|
|
Сообщ.
#6
,
|
|
|
|
Цитата rmf @ ни одного static'a в проекте нету, а всё равно этот хренов crt, чё делать? Ну, а то же самое, только на глобальном уровне (не в функциях)? ![]() ![]() int x = f(); SomeClassWithCtorOrDtorOrVTable obj; |
|
Сообщ.
#7
,
|
|
|
|
Кароче, искал я такие места в программе, не нашел ничего подозрительного, немного подумав, ввел строчку
![]() ![]() #pragma comment(linker, "/MERGE:.CRT=.text") и помогло! исчези и варнинги, и секция .crt, и размер файла уменьшился на пол кило! |
|
Сообщ.
#8
,
|
|
|
|
Ты убрал одно из следствий (варнинг), а не причину самого варнинга.
Вот тебе пример: ![]() ![]() #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-секций, которые можно было бы просто игнорировать без последствий. |
|
Сообщ.
#9
,
|
|
|
|
честно говоря не очень понимаю...
значит у меня могут быть ошибки, и программа может вылетиеть? а что в этом коде не так? |
|
Сообщ.
#10
,
|
|
|
|
Цитата rmf @ значит у меня могут быть ошибки, и программа может вылетиеть? Именно это я и хотел сказать. Цитата а что в этом коде не так? А ты скомпильни и запусти Раз ты тут не видишь, то возможно, что и у себя что-то мог пропустить... |
|
Сообщ.
#11
,
|
|
|
|
Ок, примерно понял в чём проблема...
в строке char* g_psz = f(); т.е. если при объявлении присваивать то ничего не получается, а если в коде то все ок, а как можно исправить эту ошибку? просто в коде присваивать? |
|
Сообщ.
#12
,
|
|
|
|
Цитата rmf @ Ок, примерно понял в чём проблема... в строке char* g_psz = f(); т.е. если при объявлении присваивать то ничего не получается Да, но не всё. Происшедшее называется динамической инициализацией (в отличие от статической, когда значение может быть посчитано на этапе компиляции/линковки и просто записано в область памяти переменной, например: char* g_psz = "abc";) Грубо говоря, в данной секции и содержатся указания стартовому коду (который я отключил через /ENTRY) выполнить функцию f() и её результат присвоить переменной g_psz. Лишь после всех инициализаций стартовый код зовет main(). Аналогично - с вызовами конструкторов глобальных объектов. |
|
Сообщ.
#13
,
|
|
|
|
Я на си перешел не давно(с 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++ |
|
Сообщ.
#14
,
|
|
|
|
Цитата 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к жалко. Офигеть... |
|
Сообщ.
#15
,
|
|
|
|
Цитата Сам себе геморрой и ищешь.... 6к жалко. Офигеть... Мда... наверное ты прав, но на си я перехожу из-за маленького размера, хочется пользоватся этой возможностью по полной! Цитата Цитата 4 - и после замены этих ф-ций, размер останется таким какой стал? 5.5 кило, Не думаю. 6 кило, кода > 500 строчек!, это мне кажется оочень хороший результат! но блин, из списка вызываемых библиотек, и ф-ций исчез только strstr и strrchr!!! хотя заменил все ф-ции! в чем может быть дело? (memcpy и memsetостались, хотя ниоткуда не вызываются!) |
|
Сообщ.
#16
,
|
|
|
|
Цитата rmf @ Цитата Сам себе геморрой и ищешь.... 6к жалко. Офигеть... Мда... наверное ты прав, но на си я перехожу из-за маленького размера, хочется пользоватся этой возможностью по полной! Переходи на ассемблер - там всего будет по-полной... Цитата но блин, из списка вызываемых библиотек, и ф-ций исчез только strstr!!! хотя заменил все ф-ции! в чем может быть дело? ![]() Значит, кто-то продолжает их юзать. /NODEFAULLIB применял? |
|
Сообщ.
#17
,
|
|
|
|
и на асме пробовал, далье программ типа вызова нескольких апи не решился пойти, решил на си остановится!
угу, получаю myprj.obj : error LNK2001: unresolved external symbol _memcpy myprj.obj : error LNK2001: unresolved external symbol _memset Цитата Значит, кто-то продолжает их юзать. Кто? в коде нету их вызова! |
|
Сообщ.
#18
,
|
|
|
|
Цитата rmf @ Цитата Значит, кто-то продолжает их юзать. Кто? в коде нету их вызова! Компилятор. Вполне может memset вставить на безобидную конструкцию вроде int a[1000] = { 0 }; Выход - напиши свою функцию memset и memcpy, чтобы он не волновался |
|
Сообщ.
#19
,
|
|
|
|
Хм.. вот это я сглупил, точно, можно было создать ф-ции с этми именами,
но вот ещё что случилось теперь показывает ошибку .\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 |
|
Сообщ.
#20
,
|
|
|
|
Цитата 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 Попробуй написать: ![]() ![]() #pragma function(memset, memcpy) |
|
Сообщ.
#21
,
|
|
|
|
#pragma function(memset, memcpy), угу, 2 ошибки ичесли, а что она делает?
FillMemory - это макрос, и раскрывающийся в memset т.е. FillMemory это не замена memset, а всего лишь вызов memset, и надо написать свой аналог memset? правильно понял? |
|
Сообщ.
#22
,
|
|
|
|
Цитата rmf @ #pragma function(memset, memcpy), угу, 2 ошибки ичесли, а что она делает? Это указание компилятору не пытаться использовать встраиваемые версии данных фукнций. Цитата т.е. FillMemory это не замена memset, а всего лишь вызов memset, и надо написать свой аналог memset? правильно понял? Да. |
|
Сообщ.
#23
,
|
|
|
|
Используй RtlFillMemory и иже с ним из kernel32.lib. Тока на одноименные макросы не нарвись
Добавлено Нечто вроде ![]() ![]() #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); |
|
|
|
|
|
Ну а как сделать? пишу что то типа
![]() ![]() 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)? |
|
Сообщ.
#25
,
|
|
|
|
Цитата rmf @ Как полностью замениить memset (ну и memcpy)? Ну напиши сам-то. ![]() ![]() /*** *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); } |
|
Сообщ.
#26
,
|
|
|
|
Ну дык еслибы знал бы, написал бы!
(яж говорю, я с Delphi, и особо не понимаю, смысл этого- выделение, осовобождение памяти, и т.д. Как там легко сделать str1:=str1+str2+'hello', а здесь... ф-ции вызывать) Ты где этот код взял(дай пожалуйста и на strrchr и strstr, а то я свои версии сделал, но не уверен что они безглючные, и лучше MS'овских)? На Go To Defenition другое совсем! Добавлено З.Ы. пасибо большое, столько времени потратил на меня! |
|
Сообщ.
#27
,
|
|
|
|
Всё, спасибо, нашел сам!
C:\Program Files\Visual Studio 8\VC\crt\src |