2012-07-25 13 views
15

Czy jest to złą praktyką używanie wersji Release biblioteki innej firmy w pliku binarnym debugowania?Mieszanie biblioteki debugowania i wydania/binarnej - zła praktyka?

Używam biblioteki innej firmy i skompilowałem bibliotekę release .lib. Mój exe pracuje w trybie debugowania. Potem dostałem:

error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in test1.obj 

Po pewnym googling odkryłem, że to dlatego, że staram się mieszać zwolnienie z debugowania, a ja muszę prawdopodobnie skompilować bibliotekę w trybie debugowania lub inaczej radzić z makra _ITERATOR_DEBUG_LEVEL. Ale jestem ciekawy, czy to jest polecany sposób i dlaczego. Wydaje mi się kłopotliwe, że muszę skompilować i zachować zapis zarówno plików binarnych do wydania, jak i debugowania dla każdej biblioteki trzeciej strony, z której zamierzam korzystać, co niedługo nastąpi, nie mając zamiaru debugować tego kodu.

+0

Nie możesz skontaktować się z tą stroną trzecią, aby uzyskać wersję debugowania lub samodzielnie zbudować wersję debugowania? –

+0

To więcej niż zła praktyka: prawie gwarantuje się, że program się zawiesza lub wykonuje Złe rzeczy. Przed VS2010 można mimo to połączyć, aby wykryć dziwne błędy w czasie wykonywania. Teraz przynajmniej ci się nie uda. –

+1

@JesseGood Tak Mam kod źródłowy i właśnie skompilowałem wersję debugowania. Problem rozwiązany. Właśnie zastanawiałem się, czy mogę uciec z kompilacją i śledzeniem jednego trybu. Najwyraźniej nie! –

Odpowiedz

26

Mieszanie kodu debugowania i zwolnienia to zła praktyka. Problem polega na tym, że różne wersje mogą zależeć od różnych podstawowych części biblioteki wykonawczej C++, takich jak sposób alokacji pamięci, struktury dla rzeczy takich jak iteratory mogą być różne, dodatkowy kod może być generowany do wykonywania operacji (na przykład sprawdzanych iteratorów).

Jest to to samo, co mieszanie plików biblioteki zbudowanych z dowolnymi innymi ustawieniami. Wyobraź sobie, że plik nagłówkowy zawiera strukturę używaną zarówno przez aplikację, jak i bibliotekę. Biblioteka jest zbudowana z modułem pakowania i wyrównania ustawionego na jedną wartość, a aplikacja zbudowana z inną. Nie ma gwarancji, że przeniesienie struktury z aplikacji do biblioteki będzie działało, ponieważ mogą różnić się wielkością i pozycjami członków.

Czy można budować biblioteki innych firm jako biblioteki DLL? Zakładając, że interfejs do dowolnej funkcji jest czystszy i nie próbuje przekazać żadnych obiektów STL, będziesz mógł bez problemu mieszać aplikację do debugowania z plikami DLL wydania.

+0

W szczególności pojemniki standardowe i iteratory są różne i niezgodne. To jest sprawdzanie, które widzisz: wpływa na układ iteratorów, dodając dodatkowe pola. Std :: string stuff (only) ma wsparcie kompatybilności między Debug and Release, ale nic więcej w stl w ogóle nie zadziała. –

+2

@ JDługosz std :: string jest jawnie niezgodny pomiędzy środowiskami wykonawczymi. Zabawnym ćwiczeniem jest utworzenie biblioteki DLL z funkcją '__declspec (dllexport) std :: string make_string()', kompilacja Debugowania, następnie kompilacja Release executable, link i wywołanie funkcji. Kiedy próbowałem 'std :: cout' zwracać ciąg, wynikowa awaria była dość dramatyczna. Używa VS2013, ale był to na pewno problem z VS2010 i oczekuję również innych wersji. [Here's] (https://blogs.msdn.microsoft.com/vcblog/2014/06/10/the-great-c-runtime-crt-refactoring/) trochę informacji z ust konia. – Rai

+0

Cóż, konkretna wersja, którą wykopałem, zawierała kod do debugowania i wypuszczania std stringów (iteratora lub wartości, nie pamiętam więcej) wzajemnie kompatybilnych. Uważam, że był starszy niż VS2010, ale nie pamiętam dokładnie, jak dawno temu był. –

5

Fakt, że się nie kompiluje, powinien wystarczyć do udowodnienia, że ​​jest to zła praktyka.

Jeśli chodzi o utrzymywanie oddzielnych buildów - nie trzeba tego robić. Oto obejście, które wcześniej działało dla mnie:

#ifdef _DEBUG 
#define DEBUG_WAS_DEFINED 
#undef _DEBUG 
#endif 

#include <culprit> 

#ifdef DEBUG_WAS_DEFINED 
#define _DEBUG 
#endif 

Daj mi znać, jeśli to działa dla Ciebie.

Powiązane problemy