Start Kontakt

Moje pierwsze doświadczenia z C++20

Najwyższy czas, aby zapoznać się z wersją C++20 i przetestować ją w środowisku komputerowym. Jak zawsze w takich przypadkach lubię zaczynać naukę od prostych zagadnień, a następnie na podstawie uzyskanych doświadczeń rozwijać wiedzę.

Na pierwszy ogień poszły więc moduły. O tym, czym one są i jak się ich używa, napiszę w kolejnym artykule. Teraz chciałbym jedynie pokazać, że nawet w przypadku najprostszego programu mogą się pojawić problemy. Używam Microsoft Visual Studio, co też miało znaczenie.

Utworzyłem projekt, w jego właściwościach w opcji C++ Language Standard wybrałem ISO C++20 Standard (/std:c++20), a następnie postanowiłem do C++20 dopasować klasykę, czyli program typu "Witaj, świecie!". Oto jego wersja pierwotna:

#include <iostream>

int main()
{
    std::cout << "Witaj, świecie!\n";
}

Program docelowy miał być następujący:

import <iostream>;

int main()
{
    std::cout << "Witaj, świecie!\n";
}

Jak widać, modyfikacja miała być minimalna - należało zamiast pliku nagłówkowego wczytać moduł. Za pierwszym razem zapomniałem o tym, że instrukcję import należy zakończyć średnikiem. Po poprawieniu tego błędu myślałem, że reszta będzie już bułką z masłem. Okazało się jednak, że pojawił się dziwny błąd C7612 ("could not find header unit..."):

error C7612

Poszperałem w internecie i znalazłem informację, że w przypadku Visual Studio pojawiają się takie problemy, a rozwiązaniem jest włączenie opcji kompilatora Scan Sources for Module Dependencies:

scan sources for module dependencies

Niestety, z tego, co się dowiedziałem wynika, że włączenie tej opcji przedłuża czas kompilacji, ponieważ są wtedy skanowane wszystkie pliki źródłowe, a nie tylko interfejsy modułów i nagłówki. Alternatywą jest utworzenie oddzielnej biblioteki statycznej. Tak czy owak, mamy dużo kombinacji w przypadku tak prostej rzeczy.

Postanowiłem więc dla pewności zaktualizować do najnowszej wersję kompilatora, tym bardziej, że już kilka dni temu pojawiła się informacja, iż takowa jest dostępna. Wersję kompilatora staram się zachowywać jak najnowszą - poprzednio aktualizowałem w przybliżeniu miesiąc temu. Po zaktualizowaniu do wersji 16.11.9 przeprowadziłem test: wyłączyłem opcję Scan Sources for Module Dependencies i ponownie spróbowałem skompilować program. Okazało się, że kompilacja zadziałała bez problemu. Trudno mi orzec, czy opcja skanowania wszystkich plików źródłowych jest teraz wykonywana niejawnie, czy też zostało zmienione coś innego. W każdym razie uzyskałem działający program.

Ponieważ chciałem w konsoli wyświetlić tekst Witaj, świecie z poprawnie wyglądającymi polskimi literami, na początku funkcji main dodałem wiersz setlocale(LC_ALL, "");. Co ciekawe, kompilator podświetlił LC_ALL jako nieznany identyfikator:

LC_ALL nieznany identyfikator

Najciekawsze było to, że kompilacja działała poprawnie - błąd występował tylko w samym edytorze podczas analizy kodu programu "w tle".

Ponownie przeprowadziłem test: zamieniłem import na standardowy #include i okazało się, że podświetlenie błędu zniknęło. Wygląda na to, że w przypadku użycia modułów IntelliSense jakoś nie radzi sobie z wyszukiwaniem nazw.

Aktualizacja Okazuje się, że po zaktualizowaniu środowiska do wersji 16.11.10 błąd znów się pojawił, więc musiałem ponownie zaznaczyć opcję kompilatora Scan Sources for Module Dependencies, aby poprawnie dołączać moduły biblioteczne, np. locale lub iostream.

Następnie utworzyłem swój pierwszy moduł. Tu nie było już niespodzianek - program zadziałał bez żadnego problemu. Więcej o modułach postaram się napisać w kolejnym artykule.