2010-09-07 12 views
5

Podczas przeglądania bazy kodu Visual C++ znalazłem następujące dziwne rzeczy. Assert run-time (co jest sprawdzić stan i wyjątek, jeśli warunek jest łamane) został użyty w przypadku, gdy warunek może być oceniana w czasie kompilacji:Jakiś powód, aby użyć asercji podczas pracy zamiast asercji w czasie kompilacji?

assert(sizeof(SomeType) == sizeof(SomeOtherType)); 

wyraźnie kompilator oceni stan i zastąpić kod, który będzie skutecznie być

assert(true); 

który nic nie robi lub

assert(false); 

, który zgłasza wyjątek za każdym razem, gdy kontrola przechodzi przez tę linię.

IMO A assert kompilacji powinien być stosowany zamiast z następujących powodów:

  • byłoby wystawiać naruszenie warunku wcześniej - w czasie kompilacji - i
  • to niech czystsze (w ten sposób szybciej i mniejszy) kod maszynowy powinien być emitowany

Wygląda na to, że zapewnienie praw autorskich podczas kompilacji jest jedyną słuszną rzeczą. Czy jest jakikolwiek powód, aby preferować tu występowanie w czasie wykonywania?

+3

Wygląda jak WTF dla mnie. – egrunin

+0

'assert' zwykle nie rzuca wyjątku, ale raczej przerywa program. –

+0

Na razie nie ma standardowego dowodu kompilacji. Ten fakt jest dość ważny, szczególnie w starszych bazach kodu. –

Odpowiedz

15

Nie ma powodu, aby preferować występowanie w czasie pracy tutaj. Powinieneś preferować błędy w czasie kompilacji w stosunku do błędów w czasie wykonywania, więc nigdy nie ma powodu, by wybrać opcję między tymi dwoma, aby wybrać asercję wykonawczą.

Jednakże, jeśli asertywność statyczna nie jest opcją (nie zna pojęcia dowodu statycznego, nie wie jak go utworzyć i nie ma dostępnego, lub wie, jak je wykonać, ale nie ma czasu, aby to zrobić), aseria czasu pracy jest kolejną najlepszą rzeczą.

Z C++ 0x, wbudowana funkcja static_assert powinna zakończyć wszelkie powody, by użyć asercji wykonawczej, w której działa asercja czasu kompilacji.

4

Nie możemy powiedzieć bez kontekstu. W kodzie szablonu niektóre gałęzie mogą być nieosiągalne dla niektórych wystąpień. Twierdzenie podczas kompilacji byłoby niewłaściwe, ponieważ sprawia, że ​​cała funkcja jest zniekształcona. assert(<type-dependent expression>) nie.

E.g.

template <typename T> void foo(T t) 
{ 
    if (t < 0) { 
    assert(std::numeric_limits<T>::min() < 0); 
    T u = t - std::numeric_limits<T>::min(); 
    } 
} 

Asercji nie można przekonwertować na aserię statyczną, nawet jeśli assert podczas wykonywania nigdy się nie zawiedzie.

+0

Dlaczego nie można tego zrobić jako 'static_assert'? – GManNickG

+0

'assert (std :: numeric_limits :: min <0);' zawsze kończy się niepowodzeniem, niezależnie od T. – usta

+0

@usta: komentujesz brak wywołania funkcji? @MSalters: Myślę, że chciałeś 'min()' –

Powiązane problemy