Czy eksperymentalne cechy nowoczesnego C ++ są niezawodne w długoterminowych projektach?

87

Mam projekt, który obecnie używa C ++ 11/14, ale wymaga czegoś takiego std::filesystem, co jest dostępne tylko w C ++ 17, stąd nie mam szansy, aby go obecnie używać. Widzę jednak, że jest dostępny w moim obecnym kompilatorze jako std::experimental::filesystem. Czy warto korzystać z funkcji eksperymentalnych, zakładając, że w przyszłości mógłbym dodać coś takiego:

#ifdef CXX17 //if this is C++17
std::filesystem::something ...;
#else
std::experimental::filesystem::something ...;
#endif

Moje obawy to:

1. Czy gwarantuje się, że wszystkie zgodne kompilatory mają te same funkcje eksperymentalne?

2. Czy funkcje eksperymentalne są podatne na duże zmiany, które czynią je zawodnymi?

Może jest więcej rzeczy do zastanowienia. Dlaczego powinienem lub nie powinienem ich używać? Zaintrygował mnie nowy projekt i nie wiem, na co zdecydować.

Fizyk kwantowy
źródło
25
czy słowo eksperymentalny nie odpowiada na twoje pytania?
101010,
6
Głównie kwestia gustu, ale unikałbym zaśmiecania kodu #idef CXX17. IMHO, przenośnym sposobem jest umieszczenie całego kodu związanego z systemem plików w jednej jednostce kompilacji (może to być klasa), użycie go w pozostałych częściach kodu, zakodowanie w aktualnym standardzie C ++ 11/14. Udokumentuj, dlaczego tak to piszesz, i ostatecznie przenieś go do C ++ 17 później w fazie konserwacji, jeśli ma to sens. (komentując pierwotne pytanie)
Serge Ballesta
4
Kandydat do standardu był tylko „eksperymentalny”. Nie jest to odzwierciedlenie jakości kodu.
Galik
5
Było sporo zmian pomiędzy "eksperymentalną" a ostateczną wersją C ++ 17, patrz dokument P0492R1
Bo Persson,
7
W przypadku, gdy filesystemużywasz go znacznie mniej ryzykujesz niż inne rzeczy, ponieważ już wiesz, że jest on standaryzowany w C ++ 17, a dokładna jego specyfikacja w C ++ 17 jest publicznie dostępna. Więc wszystko, co musisz zrobić, to upewnić się, że używasz tylko experimental::filesystemfunkcji, które są w specyfikacji C ++ 17. I oczywiście musisz wiedzieć, że wszystkie docelowe platformy obsługują jedną z experimental::filesystemlub C ++ 17 std::filesystem.
Howard Hinnant,

Odpowiedzi:

79
  1. Czy gwarantuje się, że wszystkie zgodne kompilatory mają te same funkcje eksperymentalne?

Nie, funkcje eksperymentalne są opcjonalne.

  1. Czy funkcje eksperymentalne są podatne na duże zmiany, które czynią je zawodnymi?

Tak, komitet C ++ może nawet zdecydować o porzuceniu funkcji lub w procesie standaryzacji może pojawić się defekt, który wymusiłby zmianę funkcji.

Generalnie poleganie na funkcjach eksperymentalnych nie jest dobrym pomysłem. Cechy eksperymentalne są dokładnie tym, co mówi słowo (tj. Eksperymentować).

101010
źródło
2
Odnosząc się do drugiego punktu, proszę zauważyć, że mówię o funkcjach, które są już zaakceptowane, ale mogą być inne.
Fizyk kwantowy,
14
@TheQuantumPhysicist: „już zaakceptowane” to podchwytliwa koncepcja. Wszystko może zostać usunięte w dowolnym momencie poprzez późniejszą akceptację zmiany w celu jej usunięcia, i tak się stało z każdym standardem. Prawdopodobnie chciałbyś poczekać przynajmniej do projektu standardu międzynarodowego, zanim zestaw funkcji będzie w miarę niezawodny.
Kerrek SB,
1
@KerrekSB: Czy nie masz na myśli ostatecznego projektu międzynarodowego standardu znanego jako FDIS. ? Szkicowanie to dość trwały proces.
MSalters
1
@MSalters: Nie, DIS jest prawdopodobnie wystarczająco dobry, jeśli się spieszysz. I tak i tak możemy nie mieć tym razem FDIS.
Kerrek SB,
4
@KerrekSB: Prawie byłem organem krajowym Holandii w okolicach C ++ 03;). Mieliśmy krajowego sekretarza w SC22, który wiedział o procedurach ISO i jak odpowiadać FDIS, ale nie wiedział o czym. Poza naszym delegatem WG14 Randym Marques) żaden z naszych delegatów SC22 nie wiedział nic o C ++. A Randy po prostu naśmiewał się z faktu, że C ++ potrzebowałby więcej stron do zdefiniowania całego swojego UB niż C potrzebnego do zdefiniowanego zachowania - nie chciałby, żeby odpowiadał na ten FDIS;)
MSalters
50

Ktoś z publiczności zadał pytanie podczas wykładu „C ++ Standard Library Panel” na CppCon 2016 ( YouTube ) na temat potencjału nazwy experimentalodstraszającej użytkowników od używania czegokolwiek z przestrzeni nazw:

Czy uważacie, że produkcja [zawartość std::experimentalprzestrzeni nazw] jest gotowa i czy jest to argument, który można przedstawić, [że] jest to faktycznie produkcja gotowa na następne 3 lata, a może trzeba będzie zmienić kod 3 lata później?

Michael Wong (przewodniczący SG5 i SG14 oraz redaktor Concurrency TS) zadał pytanie jako pierwszy:

Myślę, że w komitecie panuje zgoda co do tego, że jest on praktycznie gotowy do produkcji. Jak powiedziałem wcześniej, w większości przypadków 99% dostaje się do środka. Chcemy mieć pewność, że nie będzie to dla Ciebie przeszkodą w korzystaniu z niej. Możesz zrozumieć, dlaczego chcemy umieszczać duże funkcje, duże grupy funkcji w takim kontekście, aby nie zakłócać reszty całego systemu bibliotecznego, ale także ułatwiać korzystanie z niego. Teraz możesz włączyć GCC z określoną flagą dla Concepts, wiesz, co w rzeczywistości ułatwia segmentowanie go.

Alisdair Meredith (były przewodniczący LWG) kontynuował:

Przyjmę tutaj przeciwne stanowisko. Jedną z rzeczy, które Herb [Sutter] powiedział jako przewodniczący WG21, standardowej grupy, kiedy wyruszyliśmy ścieżką TSes, jest taki, że nie sądził, że TSes odniesie sukces, dopóki nie zawiedliśmy w przedstawieniu czegoś do przodu, ponieważ oznacza, że ​​nie jesteśmy wystarczająco eksperymentalni, nie jesteśmy wystarczająco ambitni w tym, do czego używamy TS. Naprawdę tego chcemyexperimentalbyć wskazówką, że tak, te rzeczy mogą ulec zmianie, nie jesteśmy do tego zobowiązani i możemy coś źle zrobić. Ma to na celu obniżenie naszej bariery dla rzeczy, które uważamy za tak ambitne i osiągalne, jak tylko możemy [...] Teraz wydaje się, że standard ma trzyletni cykl wydawniczy, powinniśmy być znacznie bardziej ambitni w wprowadzaniu naprawdę eksperymentalnych funkcji do TS i być może szybciej przechodząc do samego głównego standardu. Ale znowu, będzie to dla nas zabawny temat do omówienia na kilku następnych spotkaniach [komitetu ds. Standardów C ++].

Stephan T. Lavavej (opiekun implementacji STL Microsoftu) odpowiedział jako ostatni:

Ważne jest, aby odróżnić eksperymentalność interfejsu od eksperymentalności implementacji, ponieważ kiedy mówisz „gotowe do produkcji”, co to oznacza? Zwykle „gotowe do produkcji”, można by pomyśleć o rozmowie o wdrożeniu. Całkiem możliwe, że implementacja [czegoś w std::experimental] będzie absolutnie [...] kuloodporna. [...] Coś w rodzaju [...] <random>nagłówka w TR1, [było] naprawdę, bardzo fajnie w TR1 i mogłeś mieć absolutnie kuloodporną implementację tego, ale okazało się, że interfejs się kręcił zasadniczo [przed wydaniem] C ++ 11 i [...] gdybyśmy wiedzieli wtedy, co robimy teraz, wprowadzenie experimentalbyłoby lepszym sygnałem dla ludzi, że „Hej, może nie chcesz posługiwać sięstd::experimental::variate_generator ponieważ, ha-ha, zniknie w C ++ 11 ”.

Wydaje się więc, że wśród twórców bibliotek standardowych i członków komitetów istnieje pewne pragnienie, aby przynajmniej w przyszłości zawartość std::experimentalprzestrzeni nazw miała charakter prawdziwie „eksperymentalny” i nie należy przyjmować za pewnik, że coś std::experimentalbędzie uczynić go standardem C ++.

I nie, o ile rozumiem, od dostawców bibliotek standardowych zależy, czy dostarczą implementacje dla różnych funkcji std::experimental.

Joseph Thomson
źródło
47
10 lat po pierwszym przeczytaniu tej nazwy fakt, że opiekun Microsoft STL nazywa się STL, wciąż przyprawia mnie o chichot.
Jörg W Mittag,
19
@ JörgWMittag powinieneś poznać ich opiekuna kompilatora, Michaela Sama Victora Collinsa
MM
28

„Eksperymentalny” to termin nieco przesadzony. filesystemBiblioteka powstała w Boost, i przeszedł przez kilka iteracji tam, zanim zostaną przedłożone ISO.

Jednak normy ISO są celowo bardzo konserwatywne. Nazwanie tego eksperymentem oznacza, że ​​ISO wyraźnie nie obiecuje, że nazewnictwo będzie stabilne; jest oczywiste, że w przyszłości konieczne będzie ponowne zaadresowanie kodu. Ale znając ISO, prawdopodobnie będą wskazówki, jak to zrobić.

Jeśli chodzi o zgodność między kompilatorami, spodziewaj się, że będzie ona rozsądna. Ale będą przypadki narożne (pomyślmy na przykład o ścieżkach względem dysku systemu Windows) i właśnie dlatego przyszły standard może złamać twój istniejący kod. Idealnie byłoby złamać kod wtedy i tylko wtedy, gdybyś polegał na tym narożnym przypadku, ale to nie jest gwarancja.

MSalters
źródło
8

Może jest więcej rzeczy do zastanowienia.

Kilka kwestii do rozważenia:

  • Jak wieloplatformowy jest Twój projekt? Jeśli zaangażowany jest tylko jeden kompilator, możesz sprawdzić jego implementację i historię, aby podjąć decyzję. Albo ich zapytaj!

  • Jak duży jest Twój kod? Jak duży byłby wpływ zmian?

  • Jak fundamentalne dla twojego projektu są funkcje dostarczane przez API / bibliotekę / funkcję?

  • Jakie są alternatywy?

    • Użyj funkcji eksperymentalnej, a następnie dostosuj kod do modyfikacji, gdy / jeśli zostanie ujednolicony. Może być tak łatwe, jak usunięcie experimental::, lub tak trudne, jak wymuszenie obejścia.
    • Dodaj warstwę abstrakcji (komentarz Serge Ballesta). Jeśli funkcja eksperymentalna ulegnie zmianie, ponowne zapisy są izolowane. W przypadku standardowej funkcji może to być przesada (std :: filesystem jest już warstwą abstrakcji ...).
    • Użyj innego interfejsu API / biblioteki. Te same pytania: dojrzałość? krzepkość? stabilność? ruchliwość? łatwość użycia? cechy?
  • W przypadku std :: filesystem (lub sieciowego TS) istnieje opcja boost :: filesystem (odp. Boost :: asio) jako alternatywa lub rozwiązanie awaryjne, na wypadek, gdyby experimentaljeden z nich zawiódł lub zniknął.
Pablo H.
źródło