Używanie różnych kompilatorów C ++ i wersji językowych podczas opracowywania jednego pliku wykonywalnego

15

Nasza firma kupi duży i bardzo złożony fragment kodu źródłowego do komunikacji satelitarnej.

Jest on kodowany w C ++, a my dodamy do niego dodatki, również w C ++, łącząc nasz kod z zakupionym kodem w jedną jednostkę wykonywalną.

  • Czy konieczne jest, abyśmy korzystali z tego samego kompilatora i tej samej wersji kompilatora, której użyto do opracowania zakupionego kodu?

  • Czy konieczne jest używanie tej samej wersji C ++ co zakupiony kod? Jeśli nie używa 2014, my _might_ chcesz korzystać z niektórych funkcji, ale nie, jeśli nie mogą być pewne problemy z mieszania różnych wersjach.

Teoretycznie oczywiście nie powinno to mieć znaczenia, szczególnie wersja językowa, ale można sobie wyobrazić, że różne wersje kompilatora będą generować różne kody obiektowe, co może prowadzić do różnic czasowych itp.

O czym powinniśmy wiedzieć?

Mawg mówi, że przywróć Monikę
źródło
7
Mam nadzieję, że kupujesz nie tylko kod źródłowy, ale także pewne wsparcie (przez wykwalifikowane osoby).
Basile Starynkevitch
1
Rzeczywiście jesteśmy. I oczywiście zadałem również to pytanie dostawcy. Ale pomyślałem, że będzie to dobry punkt do dyskusji i dobre odniesienie dla innych w przyszłości.
Mawg mówi o przywróceniu Moniki
2
Czy mówisz o kompilacji kodu innej firmy przy użyciu nieobsługiwanego kompilatora, czy mówisz o kompilacji różnych części kodu za pomocą różnych kompilatorów (np. Używasz obsługiwanego kodu dla kupowanego kodu i nowszego dla własnego kodu, a następnie łącząc je)? A może decydujesz między tymi częściami pytania?
jpmc26
3
Nawet wersja językowa może mieć znaczenie, zobacz gcc.gnu.org/wiki/Cxx11AbiCompatibility, aby uzyskać listę (starszych) wersji kompilatora i niewielkie różnice w ABI. Innymi słowy: ten sam kompilator, ale różne ustawienia języka c ++ (c ++ 03 s c ++ 11) mogą mieć znaczenie.
André
2
W przypadku MSVC generalnie nie jest bezpieczne przekazywanie standardowych obiektów bibliotecznych przez (dynamiczne) granice bibliotek. Zobacz na przykład stackoverflow.com/q/5661738/417197
André

Odpowiedzi:

9

Czy konieczne jest, abyśmy korzystali z tego samego kompilatora i tej samej wersji kompilatora, której użyto do opracowania zakupionego kodu?

To zależy.

Kompilatory generują kod celujący w ABI. Niektórzy używają wspólnego ABI (na przykład, jeśli się nie mylę, zarówno clang ++, jak i g ++ nazywa się Itanium ABI) i powinieneś - mogą istnieć błędy, które ci to uniemożliwiają - móc korzystać z kodu obiektowego z obu w tym samym programie (zakładając oczywiście, że używasz wersji kierowanych na tę samą wersję ABI). To samo dotyczy wersji kompilatora: niektórzy zwracają większą uwagę na zachowanie tego samego ABI między wersjami niż inne. Oczywiście wszyscy oni potrzebują kiedyś zmiany ABI i mogą być zmuszeni do zrobienia tego w niezgodny sposób. Oczywiście niektóre ustawienia, takie jak wybór standardu językowego, mogą mieć wpływ na wybór ABI.

Potem jest kwestia standardowej biblioteki. Same kompilatory (lub różne wersje tego samego kompilatora) mogą używać tego samego ABI, a jednak ich standardowa biblioteka może być niekompatybilna (a niektóre kompilatory, takie jak clang ++, mogą być użyteczne z kilkoma standardowymi bibliotekami). Możliwość uruchomienia może zależeć od tego, co jest używane w interfejsie.

Innymi słowy, musisz wykopać i znaleźć informacje dla konkretnego przypadku, w którym się znajdujesz. Jako punkt wyjścia i przykład tego, jakiego rodzaju informacji powinieneś szukać, oto informacje dostarczone przez libstdc ++ (biblioteka używana przez g ++ i w niektórych konfiguracjach przez clang ++)

AProgrammer
źródło
10
ABI = Application Binary Interface
Simon B
2
Ta odpowiedź dotyczy zgodności kodu obiektowego. OP kupuje kod źródłowy .
Lekkość ściga się z Moniką
7
@LightnessRacesinOrbit Pytanie dotyczy używania różnych kompilatorów do generowania jednego pliku wykonywalnego. Nie jest wielkim skokiem myślenie: „Mają na myśli kompilowanie kodu strony trzeciej za pomocą jednego kompilatora (prawdopodobnie„ obsługiwanego ”) i własnego kodu za pomocą innego kompilatora (prawdopodobnie nowszego).” (To jest zdecydowanie to, o co rozumiem, że OP musi pytać; jeśli czytasz to inaczej, możesz poprosić OP o wyjaśnienie.) W tej możliwości lub w innych podobnych, kompatybilność kodu obiektowego wydaje się bardzo istotna.
jpmc26
1
@ jpmc26: „Zdecydowanie o to pytam OP; jeśli przeczytasz to inaczej, możesz poprosić OP o wyjaśnienie”. OP wyraźnie stwierdził, że ich firma „kupi duży i bardzo złożony fragment kodu źródłowego”. Co więcej, dzięki takim stwierdzeniom, jak „możliwe jest, że różne wersje kompilatora będą generować różne kody obiektowe, co potencjalnie może prowadzić do różnic czasowych”, pytają o zmiany, które kompilują zakupiony kod z różnymi łańcuchami narzędzi, a nie tylko własnymi. Nie sądzę, żeby było tam dużo miejsca na interpretację!
Wyścigi lekkości z Moniką
8

Czy konieczne jest, abyśmy korzystali z tego samego kompilatora i tej samej wersji kompilatora, której użyto do opracowania zakupionego kodu? Czy konieczne jest używanie tej samej wersji C ++ co zakupiony kod?

To nie jest głównie pytanie techniczne. To pytanie prawne dotyczące tego, co piszesz w umowie. Upewnij się, że sprzedawca oprogramowania zapewnia gwarantowaną przez niego wersję do użytku w twoim środowisku. W przeciwnym razie zawsze będzie pewne ryzyko problemów z innym kompilatorem, wersją kompilatora lub wersją językową.

Jest to szczególnie ważne przy zakupie komponentu lub jego części jako zamkniętego źródła. Nawet jeśli twój dostawca gwarantuje, że możesz używać komponentu z bieżącym środowiskiem kompilatora, to czy gwarantuje, że dostarczy ci aktualizacje, jeśli chcesz w przyszłości przejść na nowszą wersję kompilatora? Jeśli nie masz dostępu do pełnego kodu źródłowego, prawdopodobnie nie będziesz miał szczęścia, próbując samodzielnie rozwiązać problemy ze zgodnością. Dlatego powinieneś nie tylko kupić oprogramowanie, ale także pomyśleć o długoterminowej umowie serwisowej z dostawcą.

Doktor Brown
źródło
To naprawdę dobra rada!
T. Sar - Przywróć Monikę
Rzeczywiście jest, ale niestety za późno. Jak zauważyłem w komentarzu Basile, zadałem to pytanie również dostawcy. Ale pomyślałem, że będzie to dobry punkt do dyskusji i dobre odniesienie dla innych w przyszłości
mówi Mawg przywrócenie Moniki
4

Nasza firma kupi duży i bardzo złożony fragment kodu źródłowego do komunikacji satelitarnej. Jest on kodowany w C ++, a my dodamy do niego dodatki, również w C ++, łącząc nasz kod z zakupionym kodem w jedną jednostkę wykonywalną.

Brzmi dobrze!

Czy konieczne jest, abyśmy korzystali z tego samego kompilatora i tej samej wersji kompilatora, której użyto do opracowania zakupionego kodu?

Mówiąc ogólnie, nie, nie jest to konieczne. Celem C ++ jest działanie jako abstrakcja tego rodzaju rzeczy, więc dobrze napisany program C ++ skompiluje się równie dobrze na twoim łańcuchu narzędzi, jak na oryginalnym autorze, a wynikowy program będzie miał taki sam wynik. Wydajność może się różnić, ponieważ różne kompilatory są dobre w różnych rzeczach, ale podstawowe zachowanie programu nie powinno się zmieniać.

Jednak źle napisane oprogramowanie może polegać na zachowaniu specyficznym dla implementacji lub nawet na niezdefiniowanym zachowaniu. Może przyjmować założenia dotyczące typów wbudowanych lub endianizmu platformy. Nawet dobrze napisane oprogramowanie może nie mieć innego wyboru, jak polegać na niestandardowych rozszerzeniach, które nie są dostępne w wybranym łańcuchu narzędzi, lub może to zrobić, ponieważ po prostu nie trzeba było tracić czasu na dodawanie warstwy przenośności w czasie oryginalny projekt.

Ostatecznie będziesz musiał zapytać autora / dostawcę, po co jest napisany kod źródłowy. Jeśli twierdzą, że jest specjalnie napisany przeciwko, powiedzmy, Visual Studio 2015 i wymaga funkcji Windows API, prawdopodobnie powinieneś się tego trzymać. Ale jeśli twierdzą, że jest przenośny, standardowy C ++, użyj dowolnego kompilatora, który ci się podoba. Upewnij się, że umowa zakupu zawiera umowę wsparcia, abyś mógł uzyskać bezpłatną pomoc, gdy okaże się, że sprzedawca kłamał.

Czy konieczne jest używanie tej samej wersji C ++ co zakupiony kod? Jeśli nie używa 2014, my może chcesz korzystać z niektórych funkcji, ale nie, jeśli nie mogą być pewne problemy z mieszania różnych wersjach.

Prawdopodobnie. Może.

C ++ 03 jest w większości kompatybilny z przyszłością, więc jeśli kod to C ++ 03, prawdopodobnie nie będzie problemu. (Chociaż niektóre poprawki mogą być wymagane.)

Ale funkcje wprowadzone w C ++ 11 i C ++ 14 nie są kompatybilne wstecz, więc jeśli dostawca użył, powiedzmy, lambda C ++ 11, a Ty spróbujesz zbudować ich kod w kompilatorze C ++ 03, który właśnie wygrał nie działa.

Teoretycznie oczywiście nie powinno to mieć znaczenia, szczególnie wersja językowa, ale można sobie wyobrazić, że różne wersje kompilatora będą generować różne kody obiektowe, co może prowadzić do różnic czasowych itp.

Absolutnie. Jeśli kod w dużym stopniu opiera się na konkretnej implementacji w celu uzyskania oczekiwanych rezultatów, to od dostawcy zależy odpowiedzialność i poinformowanie o tym. Ponieważ żyjemy w prawdziwym świecie, zalecam, aby być pilnym i najpierw zapytać ich.

I powtórzę to, co powiedzieli inni: upewnij się, że masz jakieś wsparcie, aby w przypadku fałszywej odpowiedzi na te pytania (umyślnie lub w inny sposób) nie poniosłeś wynikających z tego kosztów.

Lekkość Wyścigi z Moniką
źródło
Warto zauważyć: linkowanie nie jest w pełni uwzględnione w specyfikacjach C ++. Chociaż kod może się kompilować w wielu zgodnych kompilatorach, nie ma gwarancji, że można po prostu połączyć je ze sobą i uruchomić.
Cort Ammon
1
@CortAmmon: Powinieneś / musisz skompilować wszystkie składniki wynikowej dystrybucji za pomocą łańcuchów narzędzi, które współużytkują ABI. Standardy ABI są poza zakresem C ++. Nie sądzę, żeby OP i tak pytał o mieszanie łańcuchów narzędzi.
Wyścigi lekkości z Moniką
2

Nie łączysz kodu, łączysz skompilowane pliki obiektowe.

W takim przypadku tak, użycie różnych kompilatorów C ++ (lub nawet ustawień, takich jak kompilacje debugowania / wydania) lub różnych ich wersji lub różnych (wersji) bibliotek standardowych, gdy budowanie części, które będą oddziaływać na poziomie binarnym, najprawdopodobniej spowoduje uszkodzenie aplikacji, jeśli części komunikują się ze sobą przy użyciu więcej niż C API.

Funkcje takie jak kontenery lub wyjątki zapewniają ten sam interfejs, ale na poziomie binarnym mogą być implementowane na wiele różnych, niekompatybilnych sposobów.

Użycie innego kompilatora do skompilowania całego kodu to jednak inna kwestia. Pytania do rozważenia:

  • Na jaką platformę / architekturę działa kod?
  • Dla jakiego standardu został napisany?
  • Czy korzysta z niestandardowych funkcji kompilatora?
  • Czy kod zawiera zakodowane założenia dotyczące konkretnej platformy (jak zawsze biorąc pod uwagę, że wskaźniki zajmują 2 bajty)?

Istnieje również ryzyko, że kod może zawierać części, które powodują niezdefiniowane zachowanie. Mogą się wydawać, że działają dobrze, gdy używasz jednego kompilatora, ale zawodzą w tajemniczy sposób, gdy używasz innego.

D. Jurcau
źródło
OP buduje kod, a nie dostawcę. OP zastanawia się, w jaki sposób zmiana środowiska kompilacji (por. Producenta) może wpłynąć na generowanie kodu przy tej samej bazie kodów.
Wyścigi lekkości z Moniką
1

Czy konieczne jest, abyśmy korzystali z tego samego kompilatora i tej samej wersji kompilatora, której użyto do opracowania zakupionego kodu?

Przełączanie kompilatora może powodować pewne problemy; obecnie w mojej firmie używamy Clang i MSVC i mamy błąd w jednym kompilatorze, którego drugi nie oznacza jako taki.

Czy konieczne jest używanie tej samej wersji C ++ co zakupiony kod? Jeśli nie używa 2014, my może chcesz korzystać z niektórych funkcji, ale nie, jeśli nie mogą być pewne problemy z mieszania różnych wersjach.

Nie jest to konieczne, ale oczywiście twój kompilator powinien obsługiwać wersję C ++, której chcesz używać. C ++ gwarantuje zgodność retro począwszy od wszystkich wersji.

LaboPie
źródło
Prawie moje myślenie. Co z wersjami kompilatora - jeśli używają GCC w wersji x, a najnowszą wersją jest na przykład x + 2?
Mawg mówi o przywróceniu Moniki
1
Cóż, jeśli używają starszej wersji kompilatora, którego chcesz użyć, nie ma problemu, ponieważ nie ma czegoś takiego jak przestarzałe rzeczy, problem mógłby się pojawić, gdyby korzystali z nowszej wersji kompilatora.
LaboPie
Ale jak? Ja też wolę tego nie robić. Ale czy zdajesz sobie sprawę z wszelkiego rodzaju problemów, które mogą wystąpić?
Mawg mówi o przywróceniu Moniki
Ale czy zdajesz sobie sprawę z wszelkiego rodzaju problemów, które mogą wystąpić? Gdyby korzystali z funkcji, których nasz kompilator nie będzie obsługiwał, kod po prostu się nie skompiluje.
LaboPie
1
Mały dodatek, oczywiście problem staje się większy, jeśli kompilator używany z drugiego biura nie był duży. Na przykład stary kompilator konsoli lub coś, co działa z podzbiorem języka.
LaboPie
1

Jednym z dużych problemów podczas zmiany kompilatorów jest niezdefiniowane zachowanie: jeśli otrzymany kod wywołuje niezdefiniowane zachowanie, wówczas wszystko jest możliwe - w tym, że kod działa dobrze i przechodzi wszystkie testy podczas korzystania z ich kompilatora i bardzo źle idzie z twoim kompilatorem.

Jest to możliwe, ale w takiej sytuacji możesz również napotkać problemy, jeśli zmienisz poziomy optymalizacji, użyjesz następnej wersji tego samego kompilatora i tak dalej. Nic więc nie możesz uniknąć.

gnasher729
źródło
To dobry argument za stosowaniem kłaczków i być może valgrindu .