2013-08-02 6 views
5

Od § 17.6.4.9 ISO/IEC 14882: 2011 (E) (C++ 11):Czy implementacje C++ mogą zakładać, że dowolny parametr funkcji wartości odniesienia jest unikatowy?

Każdy z poniższych odnosi się do wszystkich argumentów do funkcji z definicją w C++ biblioteki standardowej, chyba że wyraźnie stwierdzono inaczej.
[wycinanie]
- Jeśli argument funkcji wiąże się z parametrem referencyjnym rvalue, implementacja może przyjąć, że ten parametr jest unikalnym odniesieniem do tego argumentu.

Ta specyfikacja dotyczy tylko standardowych funkcji biblioteki, ale wydaje się, że cały punkt referencji rvalue jest dla tego rodzaju założenia możliwe. Jeśli mam funkcję, która przyjmuje referencję rvalue i przekazuje ją (za pośrednictwem tymczasowego lub std::move), czy implementacja może legalnie wykonywać optymalizacje, które zakładają, że jest wyjątkowa? Jeśli nie, to czy jakieś implementacje tak czynią?

+3

Nie jestem pewien, twoje pytanie. Wydaje się, że odpowiedź jest właściwa w cytowanym tekście: "implementacja może zakładać, że ten parametr jest unikalny" –

+1

Cytat odpowiada na standardowe funkcje biblioteki. Ale co z funkcjami zdefiniowanymi w samym programie? –

Odpowiedz

5

Język sam w sobie nie wymaga, aby referencja rvalue nie mogła aliasować żadnego innego obiektu, jest to po prostu określony warunek wstępny standardowych funkcji biblioteki. Jeśli więc przez "implementację" masz na myśli kompilator, to nie - kompilator nie wykona żadnych optymalizacji w oparciu o to wymaganie, na pewno nie w kodzie, który napiszesz.

Jeśli dany kompilator ma jakieś rozszerzenia, które umożliwiają kodowi przekazywanie informacji o aliasingu, to ten warunek wstępny sprawia, że ​​standardowe funkcje biblioteki mogą korzystać z takich rozszerzeń. Ten rodzaj informacji o aliasingu może umożliwić kompilatorowi przeprowadzenie pewnych optymalizacji.

W każdym razie główną konsekwencją tego stwierdzenia jest to, że standardowa implementacja biblioteki nie musi zachowywać się rozsądnie w obliczu nieuzasadnionego aliasingu parametrów funkcji. Na przykład, jeśli skonstruować parę z

std::vector<int> some_vector(100, 42); 
auto p = std::make_pair(std::move(some_vector), some_vector); 

nie ma gwarancji, że p.first == p.second.

Brak takiego wymogu dla parametrów odniesienia o wartości l oznacza, że ​​standardowa biblioteka musi wykonać pewne szalone rzeczy, aby upewnić się, że kod taki jak vector.insert(vector.end(), vector[3]) zadziała, nawet jeśli wektor musi zostać ponownie przydzielony. Wyobrażam sobie, że komitet uznał, że nierealistyczne są implementacje, które wykrywają aliasing rinue i czasami muszą tylko przenosić.

+1

Oooh, rozumiem. "Implementacja" w ofercie odnosiła się do implementacji funkcji, a nie do implementacji języka. –

+0

@DyP Przypuszczam, że 'std :: make_pair()' jest dobrym przykładem nie-konstruktora, funkcji operatora nieprzypisującego w standardowej bibliotece, która ma więcej niż jeden argument, który może być referencją, z których przynajmniej jeden może być referencją rwartości. 'std :: make_pair (std :: move (some_container), some_container)' na przykład miałby nieokreślone wyniki. – Casey

+1

@DyP Przypisanie NIE jest przykładem, ponieważ nie może mieć wielu argumentów - nie mówiąc już o wielu argumentach, które są aliasami. Jestem idiotą, dzięki za przypomnienie. Lepiej teraz? – Casey

Powiązane problemy