Google C++ Style Guide stany żezmienić znaczenie kodu przez zastąpienie deklaracji z przodu obejmują
W skrajnych przypadkach zastąpienie #include z przodu deklaracji mogą dyskretnie zmienić znaczenie kodu.
Czy możesz mi pomóc znaleźć przykłady?
Google C++ Style Guide stany żezmienić znaczenie kodu przez zastąpienie deklaracji z przodu obejmują
W skrajnych przypadkach zastąpienie #include z przodu deklaracji mogą dyskretnie zmienić znaczenie kodu.
Czy możesz mi pomóc znaleźć przykłady?
Oto dwa przypadki. Jednym z nich jest UB, drugi myślę definiuje zmianę zachowań (zakładając brak ODR lub podobnych naruszeń: to znaczy, nikt nie zadzwonił do foo
kiedykolwiek widzi definicję A
, ale nie jestem pewien)
namespace N {
struct B {};
struct A;//:B{};
}
void foo(N::B*){
std::cout << "B\n";
}
template<class T, class=std::enable_if_t<!std::is_convertible<T*,N::B*>{}>>
void foo(T*){
std::cout << "T\n";
}
int main() {
foo((N::A*)0);
}
zastępując struct A;
z struct A:B{};
zmieni, które z przeciążeń foo
są wywoływane.
Ponadto delete A;
zadzwoni pod numer ~A()
, jeśli jest widoczny, gdy zostanie wywołane delete A;
. W przeciwnym razie, jeśli istnieje nietrywialny destruktor, mamy UB. W tym przypadku znaczenie kodu zmienia się w to, że przechodzi od UB do DB, co jest chyba zmianą znaczenia.
Jednym z najbardziej podstępnych przykładów, o których wiem, jest obsada w stylu C w połączeniu z dziedziczeniem.
Powiedzmy, że masz:
class Parent1 {};
class Parent2 {};
class Child : public Parent1, public Parent2 {};
Potem w jakiś inny plik rzucasz z Parent2 do dziecka:
Parent2* parent2_ptr = new Child;
Child* obj = (Child*)parent2_ptr;
Z pełną definicję oddanych C-styl to static_cast
, poprawnie naprawek adres. Z deklaracją forward (z Child) obsada w stylu C staje się reinterpret_cast
cicho łamiącą kod.
Nie mogę wymyślić żadnych przypadków, w których to zamienia ważny program na inny ważny program o innym znaczeniu. Ale może to łatwo doprowadzić do cichego wyświetlania programu niezdefiniowanych zachowań. Na przykład. "** 5.3.5/5 ** Jeśli usunięty obiekt ma niekompletny typ klasy w punkcie usunięcia, a cała klasa ma nietrywialny destruktor lub funkcję dealowania, zachowanie jest niezdefiniowane." –
@IgorTandetnik Czy możesz przekonwertować komentarz na odpowiedź, najlepiej za pomocą małego przykładu kodu? – Peter
ilekroć liczy się, czy dany typ jest kompletny, czy nie ma to znaczenia. – Walter