2009-02-04 11 views
5

Mój kompilator (VC++ 6.0 sp6) najwyraźniej oszalał. W niektórych fragmentach kodu widzę, że "bool mybool = true;" evalutuje i przypisuje wartość false, i na odwrót - true. Zmiana prawdziwych/fałszywych słów kluczowych na 1/0 sprawia, że ​​działa dobrze. Ten sam kod kompiluje gdzie indziej dobrze, bez zmiany prawdziwych/fałszywych słów kluczowych.C++ "true" i "false" słowa kluczowe nagle nie są prawdziwe lub fałszywe w Visual C++ 6.0

Co mogłoby to spowodować? Moją pierwszą myślą było uszkodzenie pamięci RAM lub dysku, ale wszystko wyszło dobrze. Nie jestem daleko od formatowania dysku i ponownego instalowania wszystkiego, ale jestem przerażony, że nadal widzę te same złe zachowanie.

Czy jest to technicznie możliwe, że makro lub biblioteka połączona gdzieś zepsuć znaczenie "true" i "false"?

AKTUALIZACJA: Tajemnica rozwiązana. Flaga zmiennej środowiskowej na moim komputerze została ustawiona na "false", a sposób, w jaki został interpolowany przez jakiś kod preprocesora, przedefiniował słowo kluczowe.

+0

Czy widzisz problem tylko podczas przechodzenia przez debugger, czy faktycznie zmienia on przepływ kontroli? – tsellon

+0

Czy widzisz to pod debuggerem w kompilacji wydania? Optymalizacje mogą spowodować, że zawartość zmiennych będzie nierzetelna. –

+0

Wykonujemy tylko kompilacje debugowania. Widzę te same złe zachowanie zarówno w debugerze, jak i podczas normalnego działania. – kingkongrevenge

Odpowiedz

13

Makro preprocesora z pewnością może to zrobić, choć byłoby to dość zaskakujące. Jednym ze sposobów, aby sprawdzić, czy jest to sprawa byłaby

#ifdef true 
# error "true is defined as a macro" 
#endif 
#ifdef false 
# error "false is defined as a macro" 
#endif 

odpowiedzi na komentarze:

Znajdź plik bez nagłówka, gdzie można zobaczyć ten problem, najlepiej jedną z kilku dyrektywami #INCLUDE.

Na środku listy zawiera wytyczne #ifdef #error.

jeśli błąd wyskoczy, wiesz, że jest w pierwszej połowie zawiera, jeśli nie jest w drugiej połowie. Podziel połowę na pół i powtórz. Po zawężeniu do jednego nagłówka otwórz ten nagłówek. Jeśli ten nagłówek zawiera jakiekolwiek nagłówki, powtórz proces dla listy nagłówków, które ona zawiera. W końcu powinieneś być w stanie znaleźć #defines. Żmudne, zgadzam się.

+0

TRUE i FALSE są zdefiniowane jako makra, ale są poprawnie zdefiniowane. Czy ifdef jest rozróżniana wielkość liter? W jaki sposób można uzyskać, aby preprocesor powiedział mi, GDZIE zdefiniowano makro? – kingkongrevenge

+1

#undef true #undef false USUWAJ. Ale nie mam pojęcia, gdzie znajdują się popsute #defines. Próbowałem wyrażeń regularnych przeszukując wszystkie pliki nagłówkowe, które mogę znaleźć, ale pojawiły się puste. – kingkongrevenge

+0

Edytowałem swoją odpowiedź, aby pomóc w tych pytaniach. –

3

Najprawdopodobniej plik nagłówkowy przerzuca wartości za pomocą makra - mimo to nie mogłem zaryzykować odgadnięcia. Dowolna szansa, że ​​plik jest kompilowany jako C i inne jako C++ i jest tam jakiś kod # ifdef/# define, który próbuje "naprawić" wartości true/false, ale je pomylił?

1

Jest to technicznie możliwe przedefiniowanie bool, ale nie mogę zrozumieć, dlaczego danym środowisku byłby jedynym, gdzie ten problem powierzchnie.

Może ktoś się z tobą dobrze bawi?

5

Przepełnienie bufora i zapisywanie w niezainicjowanej pamięci może również uwzględniać takie zachowanie. Na przykład, jeśli masz tablicę i bool przydzielone w sąsiednich lokalizacjach pamięci i przypadkowo napisz poza granicami tablicy.

0

Nawet w Visual Studio 2003 również czasami mi się to przydarza. Ale nie znam dokładnej przyczyny tego. Zdarza się to podczas sprawdzania wartości zwracanej przez funkcję. Mimo że zwracam wartość true z funkcji, podczas przypisywania wartości zwracanej w funkcji wywołującej, true jest konwertowane na false i false na true.

W takim przypadku sprawdzam jakiś inny parametr wyjściowy.

+0

Poważnie? To się dzieje z tobą? Jak udaje ci się napisać kod z jakimkolwiek stopniem przewidywalności, jeśli tak się stanie i nie wiesz dlaczego? –

+0

Kiedy zmieniam jakiś staroświecki kod tylko raz, gdy to się stało. Ten starszy kod nie jest dobry, ma wszystkie wady, które może mieć program :) – Vinay

+0

Ok. Brzmiało to tak, jakbyś miał ten problem regularnie. :) –

5

Jeśli widzisz ten problem podczas sprawdzania wartości zmiennych w debugerze i masz wersję wydania, może to być po prostu artefakt systemu debugowania. Najprostszym sposobem sprawdzenia tego byłoby dodać trochę kodu wzdłuż linii:

if (mybool) 
    printf("mybool is true\n"); 
else 
    printf("mybool is false\n"); 

Będziesz w stanie szybko zidentyfikować, czy debugger jest dokładna, czy nie.

4

Po pierwsze, VC6 jest pradawny i pełen błędów. Zdarzają się przypadki, w których generuje niepoprawny kod, który może być odpowiedzią na twój problem. Nie używaj VC6, jeśli masz wybór.

Po drugie, to, co widzisz, jest najprawdopodobniej wynikiem optymalizacji. Czy Twój kod zachowuje się poprawnie? Jeśli tak, po prostu debugger jest zdezorientowany, ponieważ kod, który jest wykonywany, jest inny (z powodu optymalizacji) niż kod źródłowy.

3

Niejasno przypominam sobie, że przy VC6 można uruchomić sam procesor i zobaczyć jego wydajność. Może to być przełącznik kompilatora.

W każdym razie prawie na pewno jest to wynikiem # błędów, które poszły nie tak. Jeśli było to nadpisanie pamięci, jak zasugerowano, prawdopodobnie zobaczyłbyś inne równie dziwaczne zachowania.

1

Takie problemy są przerażające, ponieważ naprawdę nie ma gdzie zacząć.

Pierwszy test, który zrobię, to przeszukanie całego kodu źródłowego twojego projektu pod kątem rzeczy, które pasują do "#define" i "true", "#define" i "false". Jeśli masz kogoś w pobliżu, kto zna Perla, to powinien być szybki skrypt.

Czy polegasz na połączeniu z niektórymi zewnętrznymi bibliotekami, które mogły ulec zmianie? Jeśli podejrzewasz jakąś dziwność z czymś, z czym się łączysz, możesz spróbować wykonać następujące kroki:

  • Utwórz program sprawdzający wartość true/false.
  • Skompiluj ten program, pamiętając o połączeniu tego programu ze wszystkimi bibliotekami kodu źródłowego.
  • Uruchom program i sprawdź, czy minimalny program wykazuje błąd prawdziwy/fałszywy, który ma wpływ na twój problem.

Jeśli ten minimalny program ma błąd, problem został przez Ciebie wyizolowany, co oznacza łączenie. Następnym oczywistym testem jest połączenie programu z niczego oprócz standardowych bibliotek C++ w celu sprawdzenia, czy kompilator jest w jakiś sposób winny.

Wreszcie, przed ponownym sformatowaniem komputera ktoś inny powinien skompilować swój kod. To naprawdę proste, a jeśli skrypt Perla nie przyniesie nic, zdecydowanie poproszę współpracownika o jakąś pomoc.

Powiązane problemy