2012-06-26 9 views
15

Byłem debugowania szczególnie podstępny błąd, który teraz wydaje mi się być spowodowane przez nieoczekiwane zmiany, które wynikają z różnych zachowań, gdy różne nagłówki są włączone (lub nie).Czy mogę uzyskać preprocesor C++ do wysyłania danych wyjściowych podczas kompilacji?

To nie jest dokładnie taka struktura mojego kodu, ale niech po prostu przyjrzeć się tym scenariuszu:

#include "Newly_created_header_which_accidentally_undefines_SOME_DEFINE.h" 

// ... 

#ifdef SOME_DEFINE 
    code_which_i_believe_i_am_always_running(); 
#else 
    code_which_fails_which_i_have_forgotten_about(); // runtime error stack traces back here, but I don't know this... or maybe it's some strange linker error 
#endif 

ja przeglądać mój git popełnia i zawężenia przyczynę błędu, kompilacji i uruchamiania mojego kodu niezliczoną ilość razy, aby znaleźć po kilku godzinach, że jedyną różnicą wymaganą do spowodowania błędu jest włączenie czegoś, co wydaje się być całkowicie łagodnym i niepowiązanym nagłówkiem.

Być może jest to świetny argument za tym, że preprocesor po prostu jest do bani.

Ale ja to lubię. Preprocesor jest świetny, ponieważ pozwala nam tworzyć skróty. To tylko niektóre z tych skrótów, gdy nie są używane ostrożnie, ugryzą nas w tyłek dość mocno.

Więc w tym momencie byłoby to pomogło, czy mogę użyć dyrektywy jak #echo "Running old crashy code" gdzie będę mógł zobaczyć ten podczas kompilacji więc mogę być ostrzeżony natychmiast rozpocząć śledztwo dlaczego SOME_DEFINE nie została zdefiniowana.

O ile znam prosty sposób określania czy SOME_DEFINE jest definiowana jest zrobić coś takiego

#ifndef SOME_DEFINE 
    printf("SOME_DEFINE not defined!!\n"); 

Będzie to z pewnością to zadanie, ale nie ma dobry powód do tego zadania będą wykonywane w środowisko wykonawcze, ponieważ jest całkowicie określone podczas kompilacji. To jest po prostu coś, co chciałbym zobaczyć podczas kompilacji.

To powiedziawszy, w tej sytuacji użycie funkcji drukowania (lub dziennika, a nawet wyrzucenia wyjątku) może być do przyjęcia, ponieważ nie będę się martwić spowolnieniem lub zagraceniem wątpliwego kodu. Ale to nie ma znaczenia, jeśli mam na przykład dwie ścieżki kodowe, z których obie są ważne, i chcę tylko wiedzieć podczas kompilacji, która z nich jest aktywowana. Musiałbym się martwić o uruchomienie kodu, który wykonuje wydruk kondycjonowany preprocesorem na początku programu.

To naprawdę tylko długotrwały sposób zadawania pytania: "Czy mogę wysłać ciąg znaków do wyjścia podczas kompilacji za pomocą dyrektywy preprocesora?"

+3

Użyj '#err lub 'dyrektywę? Lub '# warning', jeśli preprocesor go obsługuje. –

+0

'# warning' jest bardziej podobne, ponieważ nie wstrzyma przetwarzania. Ale tak, to prawie to. Proszę, odpowiedz! –

+0

Sądzę, że w niektórych kompilatorach jest również "# warn' \' # warning ", ale uważam, że jest on nietypowy i mniej uniwersalny. Widziałem także '#pragma message (" WARN ")' i '# print' na niektórych. – jedwards

Odpowiedz

18

Jeśli użyć dyrektywy #error, wyjście zostanie wydrukowany bezpośrednio i kompilacja zatrzyma:

$ make days_in_month 
cc  days_in_month.c -o days_in_month 
days_in_month.c:2:2: error: #error "ugly!" 
make: *** [days_in_month] Error 1 
$ 

To może nie być całkiem to, czego chciał, ale dostaje zadanie szybko.

$ cat days_in_month.c 
#include <stdio.h> 
#error "ugly!" 
... 

Jeśli chcesz przetwarzanie nadal można używać #warning:

$ make days_in_month 
cc  days_in_month.c -o days_in_month 
days_in_month.c:2:2: warning: #warning "ugly!" [-Wcpp] 
$ head days_in_month.c 
#include <stdio.h> 
#warning "ugly!" 
+0

Zapewni to wydruk łatwo widoczny. Tak naprawdę liczyłem na opcję, w której mogę zdefiniować dokładną strunę, którą wypluwa (więc może być tak widoczna, jak chcę), ale to dostanie zadanie. –

+0

Zauważ, że możesz umieszczać w łańcuchu co chcesz; Jeśli chcesz wyświetlić pełny ekran bloków "XXX WARNING XXX", zrób to sam. :) (Zastanawiam się czy końcówki kolorów również się przedostają?) – sarnold

+0

@Linuxios: to była moja pierwsza próba ... :) Moja pierwsza wersja tej odpowiedzi była po prostu '# error', dopóki nie pomyślałem o spróbowaniu czegoś bardziej gadatliwego - - Byłem przekonany, że widziałem sposób na wprowadzenie tylko ostrzeżenia. – sarnold

Powiązane problemy