Czy powinienem przestać używać terminu C / C ++?


140

Rozumiem, że C i C ++ są różnymi językami, ale kiedy uczyłem się C ++, zawsze mówiono mi, że C jest podzbiorem C ++ lub C ++ to C z klasami. I tak było do czasu pojawienia się C ++ x0, C ++ 11 (lub ogólnie C ++ 11/14/17). W rzeczywistości (szczególnie podczas pracy na systemach wbudowanych) bardzo prawdopodobne jest, że znajdzie kod napisany w C ++, ale z dużą ilością części napisanych całkowicie w czystym języku C. Tutaj mam kilka pytań:

  1. Czy powinienem przestać używać terminu C / C ++?
  2. Jeśli odpowiedź na pytanie nr 1 brzmi „tak”, jak miałbym wywołać program wykorzystujący mieszankę C i C ++?
  3. Biorąc pod uwagę, że oba są „różnymi” językami, jest prawdopodobne, że w pewnym momencie kompilatory C ++ przestaną obsługiwać kod napisany w języku C (ponieważ współczesne c ++ odbiega od mentalności C dla podstawowych rzeczy, takich jak wskaźniki, obsługa pamięci dynamicznej itp.)
  4. Czy istnieje obecnie jakakolwiek współpraca między ludźmi, którzy tworzą standardy C / C ++ w celu zachowania zgodności
  5. Jeśli nr 4 brzmi „tak”, taka współpraca może zakończyć się w najbliższej przyszłości wraz z pojawieniem się nowoczesnego c ++ (11/14/17)

Wiem, że są już podobne pytania, ale jestem pewien, że wiele osób dzieli się tymi pytaniami, więc jestem bardzo zainteresowany uzyskaniem dobrych odpowiedzi, szczególnie w kwestiach związanych z tendencją C ++ w najbliższej przyszłości.


35
I tak było cicho, dopóki pojawienie się C ++ x0, C ++ 11 Nie, C89 nie jest podzbiorem C ++ 98.

35
Should I stop using the term C/C++. Tak. Jest to używane tylko przez rekruterów i HR. Inżynierowie użyją tego terminu Club C++jako niezależnych języków. Jeśli znajdziesz inżyniera, który łączy ten termin, unikaj go.
Martin York

8
@LokiAstari: naprawdę? Myślę, że programiści SQLite są HR, ponieważ nie mają otwartych pozycji. Jest to niezwykle restrykcyjny pogląd (proszę, oddaj głos mojej odpowiedzi, tak jak inni w twojej sytuacji).

4
@greyfade: Źle jest zakładać, że każdy w dowolnym miejscu może rościć sobie pretensje do powszechnie widzianej sekwencji znaków. „C / C ++” może być nazwą wybraną dla określonego języka, ale to nie znaczy, że użycie „C / C ++” odnosi się do tego języka, podobnie jak gdybym skopiował tę stronę i zastąpił „C / C ++” przez „C ++ 1z”, że wszystkie dyskusje na temat projektu standardu C ++ nagle zaczęłyby używać niewłaściwej terminologii. Mówiąc najprościej, ciąg „C / C ++” nigdy nie odwoływał się do tego języka żartów o nazwie „C / C ++” i nigdy nie będzie.
Ben Voigt

32
@TomDworzański, stroustrup.com/bs_faq.html#C-is-subset "W ścisłym sensie matematycznym C nie jest podzbiorem C ++ ... Jednak C ++ obsługuje każdą technikę programowania obsługiwaną przez C ... To nie jest rzadko jest w stanie przekonwertować dziesiątki tysięcy linii C na C ++ w ciągu kilku godzin. Zatem C ++ jest tak samo nadzbiorem ANSI C, jak ANSI C jest nadzbiorem K&R C, podobnie jak ISO C ++ nadzbiór nad C ++, jaki istniał w 1985 roku. Dobrze napisany C jest również legalnym C ++. Na przykład każdy przykład w Kernighan & Ritchie: „The C Programming Language (2nd Edition)” to także program w C ++. ”
Ben

Odpowiedzi:


183

C nigdy nie był podzbiorem C ++. Najbardziej oczywistym tego przykładem jest int new;. Było to prawdą od C89 i C ++ 98, a języki stały się od siebie coraz bardziej, gdy pojawiły się nowe standardy.

Czy powinienem przestać używać terminu C / C ++

tak

Jeśli odpowiedź na pytanie nr 1 brzmi „tak”, jak miałbym wywołać program wykorzystujący mieszankę C i C ++?

Plik źródłowy jest napisany w jednym lub drugim języku. Program może składać się z kodu z wielu języków współpracujących ze sobą lub pliku wykonywalnego utworzonego przez połączenie różnych skompilowanych obiektów. Można powiedzieć, że program został napisany w C i C ++, „C / C ++” nie jest językiem.

Biorąc pod uwagę, że oba są „różnymi” językami, jest prawdopodobne, że w pewnym momencie kompilatory C ++ przestaną obsługiwać kod napisany w języku C.

3) Nigdy tego nie zrobili. char *a = malloc(10);. C i C ++ nigdy nie były w pełni kompatybilne przynajmniej tak długo, jak miały standardy ISO (nie znam wszystkich szczegółów na temat dni wstępnie znormalizowanych). kliknij łącza lub zobacz poniżej plik, który jest w porządku z C89 i wyższym, ale nie jest prawidłowy w żadnym standardzie C ++.

4) afaik nie, grupy robocze są sobie świadome, ale standardy podejmują decyzje, które są dla nich najlepsze.

/* A bunch of code that compiles and runs under C89 but fails under any C++ */

/* type aliases and struct names occupy separate namespaces in C, not in C++ */
struct S { int i; };
typedef int S;


struct Outer { struct Inner { int i; } in; };
/* struct Inner will be Outer::Inner in C++ due to name scope */
struct Inner inner;


/* default return type of int in C, C++ functions need explicit return types */
g() {
    return 0;
}


/* C sees this as two declarations of the same integer,
 * C++ sees it as redefinition */
int n;
int n;


/* K&R style argument type declarations */
void h(i) int i; { }


/* struct type declaration in return type */
struct S2{int a;} j(void) { struct S2 s = {1}; return s; }


/* struct type declaration in argument, stupid and useless, but valid */
/*void dumb(struct S3{int a;} s) { } */


/* enum/int assignment */
enum E{A, B};
enum E e = 1;


void k() {
    goto label; /* C allows jumping past an initialization */
    {
        int x = 0;
label:
        x = 1;
    }
}


/* () in declaration means unspecified number of arguments in C, the definition
 * can take any number of arguments,
 * but means the same as (void) in C++  (definition below main) */
void f();

int main(void) {
    f(1); /* doesn't match declaration in C++ */
    {
        /* new is a keyword in C++ */
        int new = 0;
    }

    /* no stdio.h include results in implicit definiton in C.  However,
     * as long as a matching function is found at link-time, it's fine.
     * C++ requires a declaration for all called functions */
    puts("C is not C++");
    {
        int *ip;
        void *vp = 0;
        ip = vp; /* cast required in C++, not in C */
    }
    return 0;
}

/* matches declaration in C, not in C++ */
void f(int i) { }

Zawsze uważam, że warto wspomnieć, że C jest podzbiorem Objective-C.


59
Objective-C został specjalnie zaprojektowany, aby być ścisłym nadzbiorem C, bez sprzecznej składni i całkowicie ortogonalnym systemem obiektowym. Jest to tak ekstremalne, że możesz wziąć część „Cel” w „Cel-C” i przykręcić ją do innych języków, tworząc np. Cel-MODULA-2. I najsłynniej, Apple Objective-C ++, który zawiera dwa całkowicie ortogonalne, nie wchodzące w interakcje, niezintegrowane systemy obiektowe.
Jörg W Mittag,

20
@masonwheeler, jeśli OP chce zobaczyć, jak wygląda rzeczywisty nadzbiór C.
xhainingx

26
„Plik źródłowy jest napisany w jednym lub drugim języku.” Powiedz to mojemu programowi, który kompiluje się zarówno jako standard C99, jak i C ++ 89. Żaden język nie jest podzbiorem drugiego, ale istnieje skrzyżowanie ich dwóch zbiorów, które jest szeroko ukierunkowane. Zobacz Lua i in.
hojny

28
@munificent Mogę napisać kod C ++, który też może działać javac, ale o co w tym wszystkim chodzi?
xhainingx

22
@munificent Przykładem programu, który można skompilować w trzech językach - C, / bin / sh i f77 - jest pozycja applin.c w IOCCC 1986. Zgodnie z twoją definicją tag C/Fortran/shma teraz sens ?! ioccc.org/years-spoiler.html#1986 .
Sjoerd,

108

Tam ma być jakiś powód, dlaczego te terminy są ze sobą tak często. Chociaż nie powinieneś mówić nauczycielowi C, że jego język jest podzbiorem C ++, tutaj jest trochę prawdy. Inni już ujawnili punkt widzenia twojego nauczyciela. Jest to bardzo miłe (i zilustrowane przykładami itp.). Ale nie mieszkamy w wieży z kości słoniowej ani w książce.

Twój wielki szef nie przejmował się dokładnie tym, jakiego języka używałeś. Jeśli on wie trochę o programowaniu, po prostu powiedz mu, że używałeś C / C ++, a to zabrzmi jak „Użyłem języka, który musi zostać skompilowany do kodu maszynowego, z bibliotekami DLL i wszystkimi skomplikowanymi rzeczami”. Jest to część „komunikacji zewnętrznej”.

Jeśli utworzysz bibliotekę, która może być obsługiwana zarówno przez C, jak i C ++, zdecydowanie chcesz nazwać ją biblioteką C / C ++. Oczywiście, ktoś podniesie rękę i zapyta, dlaczego nie nazywacie tego biblioteką C, która akurat ma opakowanie C ++, a poza tym C ++ może łączyć się z bibliotekami C, więc nie trzeba o tym wspominać. Wystarczy odpowiedzieć: „Tak, masz rację, to jest biblioteka C / C ++”. Jest to część „komunikacji wewnętrznej”.

Jeśli utworzysz analizator leksykalny dla C ++, zdziwisz się, jak dobrze działa z C. Może nawet nie będziesz musiał go modyfikować. To jest „jeśli wygląda jak kaczka itp.” część.

Itp.

Większość programów C, jakie kiedykolwiek widziałem, kompiluje się (i działa) bez modyfikacji jako kod C ++. Nie pozwól, aby kilka wyjątków lub dogmatycznych (jakkolwiek wpływowych) programistów oszukało twoją intuicję. C i C ++ są tak blisko i tak często kompatybilne, i tak często mieszane i dopasowane razem, że używany jest termin C / C ++. Jest używany, ponieważ przydatne jest opisanie tego rodzaju sytuacji, w których tak naprawdę nie ma znaczenia, czy rozważasz C czy C ++, o ile nie jest to Java ani PHP . Wiemy, że to „źle”, ale nie obchodzi nas to, jest bardziej użyteczne niż złe.

Może być nadużywane, może być głupie, ale nadal nie jestem pewna, jakie korzyści odniesiesz, będąc bardziej pedantycznym niż potrzeba i odmówię komunikowania się w sposób zrozumiały dla innych. Jeśli czujesz się nieswojo w jakiejś konkretnej sytuacji, po prostu nie używaj ogólnego terminu C / C ++, ale odpowiedniego dla sprawy (C lub C ++).

Nie bój się przyszłości. Nasze systemy operacyjne są napisane w C. Dość duża część obecnej produkcji oprogramowania C / C ++ odbywa się w C ++. Ta para jest tu na dłużej. Nikt nie interesuje się tym, że jedno stanie się bardziej niezgodne z drugim (właściwie na odwrót).

Aby sprecyzować swoje punkty:

1) To zależy. Tak, gdy może to prowadzić do zamieszania, gdy czujesz się nieswojo, lub gdy jest to po prostu złe lub poza kontekstem. Nie, kiedy uważasz, że to wystarczające.

2) nie dotyczy

3) Myślę, że nie, ale nie mam kryształowej kuli.

4) nie ma pojęcia

5) Nie sądzę, ponieważ nic nie popycha w tym kierunku


7
Komentarze zostały usunięte, ponieważ robiły się głośne.
ChrisF

3
Dlaczego to ma tak wiele pozytywnych opinii? Jest pełen niedokładności i fałszywych roszczeń!
Zaibis,

5
@Zaibis, czy byłbyś na tyle uprzejmy, aby rozwinąć, które twierdzenia są fałszywe lub niedokładne?
liczba użytkowników

3
Zgodnie z logiką C / C ++ / Objective-C / Fortran / Pascal powinno być prawidłowym wyrażeniem, ale to brzmi głupio. Problem z terminem C / C ++ polega na tym, że może oznaczać kilka rzeczy, więc nie masz gwarancji, że przekona pożądane znaczenie. W mojej praktyce ludzie zwykle rozumieją to jako „C to tylko stara prymitywna wersja C ++” i to jest po prostu źle.
martinkunev,

4
Poza C/C++istotną ważnością tego terminu, nie jest jasne, a zatem nie jest przydatne. Zgodnie z twoimi przykładami, a C/C++ librarymoże oznaczać bibliotekę C z opakowaniem C ++ lub bibliotekę C ++ z opakowaniem C. Lub może to oznaczać, że biblioteka składa się z kilku modułów, niektóre skompilowane przy użyciu C ++, niektóre skompilowane w C. Nie jest to wcale jasne. Dla mnie stwierdzenie, że biblioteka jest utworzona, C and C++jest o wiele bardziej przejrzyste lub C library with compatibility with C++też o wiele bardziej przejrzyste. I tu dwuznaczność jest tylko z dwoma językami, wyobraź sobie, że używasz tej „strategii komunikacji”, aby uzyskać więcej ...
wredny

43

Mówiąc przeciwnie, powiedziałbym, że zależy to od kontekstu .

Termin „C / C ++” zwykle nie jest odpowiedni, gdy mówi się coś w stylu „to jest program C / C ++”, ale zostało to zbadane dogłębnie w innych odpowiedziach.

Mogą jednak istnieć konteksty, w których C / C ++ może być odpowiedni.

  • Istnieją różne biblioteki, które zwykle mają zarówno C, jak i C ++ API. Myślę, że nie jest to dalekie od prawdy, jeśli nazwiesz coś takiego biblioteką C / C ++. My, ludzie, lubimy kompresować informacje, więc powiedzenie „opencv jest biblioteką C / C ++” jest krótkie, jasne i zrozumiałe, porównaj to do powiedzenia „opencv to biblioteka, która jest dostarczana z nagłówkami zarówno dla C, jak i C ++”.
  • Możesz mówić o projektowaniu i składni języka. Z punktu widzenia składni języka można powiedzieć, że język ma składnię podobną do C / C ++.
  • Organizujesz konkurs kodowania i akceptujesz oba rozwiązania napisane w C i C ++
  • Zatrudniasz nowego programistę, a większość zadań to C lub C ++, więc programista powinien znać oba języki. Jest to powszechne w programowaniu wbudowanym, gdzie C jest bardziej odpowiedni dla niektórych (zwykle bardzo małych) mikrokontrolerów, a C ++ dla innych. W takim przypadku możesz powiedzieć, że szukasz programisty C / C ++.

10
Widzę te stanowiska przeciwko ogólnemu konsensusowi w sprawie P.SO. (gdzie musisz głosować na wszystko, co wygląda na „zwinne / hype / jak The One And Unique Right Thing” i głosować na resztę) są tak mile widziane, jak zwykle. Ludzie, programowanie nie jest religią, a ta strona internetowa nie jest świętą książką.

16
Ostatnim punktem kula rzeczywiście prezentuje poważny problem: Szukam (1) dla osoby, która wiadome albo C lub C ++, (2) osoba, która zna zarówno C i C ++ lub (3) osoba, która jest zdezorientowany, aby usłyszeć te są inne języki. Nie pomagaj w powiększaniu się trzeciej puli.
5gon12eder

10
Ostatni punkt byłby lepiej wyrażony jako „programista z doświadczeniem w C i C ++”, jeśli tego właśnie szukasz. Ogłoszenie o pracę zatytułowane „programista”, które zgodnie z doświadczeniem wymaga nagłówków „C i C ++” lub „C lub C ++” nie różni się znacząco od jednego zatytułowanego „programista” i wymienia „C / C ++” jako niezbędną kwalifikację, ale jest o wiele bardziej dokładne. Osoba, której szukasz, może naprawdę docenić tę dokładność wypowiedzi.
CVn

10
W języku pisanym „/” jest zwykle interpretowane jako logiczne or, a nie logiczne xor. Więc jest to jedno lub oba. W ofertach pracy znasz C lub C ++ lub oba. Teraz czuję, że wielu ludzi jest religijnych na temat tego terminu. Dobry programista C będzie perfekcyjnie zbierając C ++ niezależnie od tego, jak różni oba języki. Zacząłem kodować PHP, a potem przeniosłem się na Scalę (dwa zupełnie różne języki). Dlaczego programista C nie byłby w stanie wybrać C ++ lub viceversa? Termin C / C ++ ma pewną wartość, jeśli jest używany w odpowiednim kontekście.
ILikeTacos

4
Możesz także użyć C / C ++ do opisania programu, który ma działać po skompilowaniu jako C lub C ++, lub programu z osobnymi komponentami C i C ++.
immibis

30

Zasadniczo użytkownicy SO proszą osobę, która zadaje pytanie, o wybór języka: C lub C ++. Dlaczego?

Istnieje wiele subtelnych różnic między C i C ++. Na przykład w C ++ constzmienna o zasięgu globalnym ma wewnętrzne powiązanie, chyba że zadeklarowane extern, ale w C ma zewnętrzne powiązanie, chyba że zadeklarowane static. Mówiąc „C / C ++”, OP zapewnia wiedzę, że odpowiedź na ich pytanie jest taka sama zarówno w C, jak i C ++, kiedy może nie być. To niepotrzebnie utrudnia potencjalnym odbiorcom odpowiedzi.

  • Czasami możemy zauważyć, że kod jest nieprawidłowy w jednym lub drugim języku (na przykład niejawne konwersje z void*na wskaźnik na obiekt nie są poprawne w C ++). To denerwujące. Dlaczego mówisz „C / C ++”, gdy masz fragment kodu, który jest poprawny w C, ale nie w C ++? Czy miałeś zamiar C, czy to tylko błąd w kodzie przeznaczonym do C ++?

  • Czasami odpowiedź będzie inna w zależności od języka (na przykład tablice o zmiennej długości istnieją w C99, ale nie w C ++). Jeśli nie wiemy, o jakim języku mówisz, musimy zgadnąć lub napisać odpowiedź na oba, gdy tylko jeden będzie rzeczywiście przydatny, ponieważ wiesz, którego języka faktycznie używasz; po prostu nam nie mówisz!

  • Czasami odpowiedź jest naprawdę taka sama dla obu języków, ale trudno być pewnym. Na przykład uważam, że C i C ++ mają te same reguły konwersji liczb całkowitych, ale aby być naprawdę pewnym, muszę uważnie przeczytać oba standardy. Ponownie sprawia to, że wykonuję dwa razy więcej pracy, niż to konieczne, gdy zapewne zależy ci tylko na jednym z języków.

W każdym razie, aby odpowiedzieć na inne pytania:

  1. Tak.

  2. Jeśli łączysz ze sobą kod C i C ++, dopuszczalne jest użycie obu tagów, ale określ język, w którym znajduje się każdy plik.

  3. Czasami zdarzają się przełomowe zmiany, ale są one rzadkie i zazwyczaj mają ograniczony wpływ (w przeciwnym razie nie zostaną zatwierdzone). Na przykład autow C ++ 11.

  4. Nie sądzę, że współpracują bezpośrednio, ale zwracają uwagę na zmiany w innym języku i starają się unikać wprowadzania zmian, które utrudniają kompatybilność.

A jeśli naprawdę chcesz wiedzieć o obu językach, to w porządku i możesz to powiedzieć w swoim pytaniu. Kiedy mówisz „C / C ++”, tak naprawdę nie jestem pewien, co masz na myśli, i wygląda na to, że przyjmujesz założenie dotyczące dwóch języków.


7
Wiem, że są ludzie, którzy piszą kod na przecięciu C i C ++ i używają kompilatora C ++ do sprawdzania typów, ale kompilatora C do generowania kodu. Nie mam jednak pojęcia, czy to ma sens, czy nie. Jest to jednak temat, który pojawia się co kilka lat na liście mailingowej jądra Linuksa, gdy ktoś przesyła łatkę zmieniającą nazwę (bardzo ważną w Unified Object-Oriented Model Driver jądra Linuksa) struct classna coś podobnego struct klassz tego właśnie powodu, i następnie zostaje niezmiennie zestrzelony przez Linusa.
Jörg W Mittag

3
@ JörgWMittag: Nigdy nie spotkałem nikogo, kto użyłby „C / C ++” jako skrótu dla „wspólnego podzbioru C i C ++”, a także wiedziałem, o czym on mówi. Ludzie, którzy celowo pracują we wspólnym podzbiorze, często wyrażają to jasno, nie skracając ich.
Bart van Ingen Schenau

2
To dobra odpowiedź, szczególnie na temat używania C / C ++ w pytaniach Stack Exchange , a nie ogólnie.
immibis

@BartvanIngenSchenau Ilu członków std spotkałeś?
ciekawy

18

Zawsze mi mówiono, że C jest podzbiorem C ++ lub C ++ to C z klasami. I tak było cicho, aż do pojawienia się C ++ x0, C ++ 11 (lub ogólnie C ++ 11/14/17).

C nigdy nie był podzbiorem C ++. Na przykład C89 nie jest podzbiorem C ++ 98.

Kilka przykładów:

  • formularz listy identyfikatorów C89 dla deklaracji parametrów funkcji nie jest obsługiwany w C ++
  • C89 i C ++ 98 mają różne typy stałych znaków
  • C89 i C ++ 98 mają różne typy literałów łańcuchowych
  • operatory logiczne dają różne typy w C89 i C ++ 98 ( intvs bool)
  1. Czy powinienem przestać używać terminu C / C ++?

Tak.

  1. Jeśli odpowiedź na pytanie nr 1 brzmi „tak”, jak miałbym wywołać program wykorzystujący mieszankę C i C ++?

Programem jest C lub C ++ (nawet jeśli jakiś bardzo prosty program można skompilować z kompilatorem C lub C ++). Jakiego kompilatora używasz do jego kompilacji? Powinien odpowiedzieć na twoje pytanie. Harbison i Steele wymyślili termin Clean C, aby określić wspólny podzbiór C i C ++, ale myślę, że to zły pomysł.

EDIT : Przyznaję jednak, że technicznie można połączyć pliki obiektów C i C ++ w jednym programie, ale OTH istnieje wiele języków, które mogą być mieszane w jednym programie, na przykład Java i C ++. Myślę, że użycie terminu program C / C ++ tylko zwiększa zamieszanie, że jest napisany w jednym języku o nazwie C / C ++.

  1. Biorąc pod uwagę, że oba są „różnymi” językami, jest prawdopodobne, że w pewnym momencie kompilatory C ++ przestaną obsługiwać kod napisany w języku C (ponieważ współczesne c ++ odbiega od mentalności C dla podstawowych rzeczy, takich jak wskaźniki, obsługa pamięci dynamicznej itp.)

Istnieje wiele funkcji (na przykład: tablica o zmiennej długości, elastyczny element tablicy _Generic, ...) C99 lub C11, które nie są obsługiwane przez żadną wersję C ++.


Ponownie wielojęzyczne programy: program korzystający z JNI można nazwać programem C / Java. Fakt, że dwa języki są używane razem, nie oznacza, że ​​są one kompilowane razem.
immibis

1
stroustrup.com/bs_faq.html#C-is-subset "W ścisłym matematycznym sensie C nie jest podzbiorem C ++ ... Jednak C ++ obsługuje każdą technikę programowania obsługiwaną przez C ... Nie jest to rzadkie potrafi konwertować dziesiątki tysięcy wierszy C ++ w stylu C ++ w ciągu kilku godzin. Zatem C ++ jest tak samo nadzbiorem ANSI C, jak ANSI C jest nadzbiorem K&R C, a ISO C ++ jest nadzbiorem C ++ tak jak istniało w 1985 r . Dobrze napisane C jest również legalnym C ++. Na przykład każdy przykład w Kernighan & Ritchie: „The C Programming Language (2nd Edition)” to także program w C ++. ”
Ben

@Ben pierwszy program (hello world) w „The C Programming Language (2nd Edition)” pomija typ zwracany przez main, który jest niepoprawny w C ++.
ouah

1
@ouah, wygląda na to, że profesor Stroustrup przeoczył jedną z nich :-) Zauważ, że nie jest to dozwolone również w C11 :-) Jednak jestem pewien, że było to dozwolone we wcześniejszych wersjach C ++.
Ben

4
@ tak, to nie jest pierwsza wersja C ++. Książka pochodzi z 1988 roku i wówczas żaden język nie był standardem ISO. Obecna wersja C ++ w tym czasie była książką Bjarne Stroustrup z 1985 roku.
Ben

17

Niektóre programy są napisane w kombinacji C i C ++

To tylko fakt z życia. Możesz skompilować pliki obiektowe z C i C ++ i połączyć je ze sobą. Wynik można całkiem rozsądnie nazwać „programem C / C ++”.

Ale to tylko program jako całość. Co z poszczególnymi jednostkami kompilacji?

Istnieje podzbiór C, który jest również podzbiorem C ++

Program (lub jednostka kompilacji) napisany w tym podzbiorze będzie się kompilował i zachowywał tak samo w zgodnych kompilatorach C i C ++. Taki program lub plik można słusznie nazwać „programem C / C ++” lub „plikiem C / C ++”.

Program częściowy, taki jak plik nagłówkowy, może być również używany zarówno w programach C, jak i C ++. Takie pliki nagłówków można słusznie nazwać nagłówkami C / C ++.

Cytując profesora Bjarne Stroustrup:

Czy C jest podzbiorem C ++?

W ścisłym sensie matematycznym C nie jest podzbiorem C ++. Istnieją programy, które są poprawne w C, ale niepoprawne w C ++, a nawet kilka sposobów pisania kodu, który ma inne znaczenie w C i C ++. Jednak C ++ obsługuje każdą technikę programowania obsługiwaną przez C. Każdy program C może być napisany zasadniczo w ten sam sposób w C ++ z takim samym czasem działania i wydajnością przestrzeni. Często zdarza się, że w ciągu kilku godzin można konwertować dziesiątki tysięcy linii ANSI C na C ++ w stylu C. Zatem C ++ jest tak samo nadzbiorem ANSI C, jak ANSI C jest nadzbiorem K&R C, podobnie jak ISO C ++ jest nadzbiorem C ++, jaki istniał w 1985 roku.

Dobrze napisane C zwykle jest również legalnym C ++. Na przykład każdy przykład w Kernighan & Ritchie: „The C Programming Language (2nd Edition)” to także program w C ++.

Więc tak istnieje coś takiego jak C / C ++. Jest to wszystko, co jest zarówno poprawnym C, jak i poprawnym C ++.

Preprocesor C jest częścią języka C. Preprocesor C ++ jest częścią języka C ++

Możesz napisać jednostkę kompilacji, która skompiluje się w C lub C ++ i będzie inna . Na przykład może mieć podstawową funkcjonalność skompilowaną w C, ale skorzystać z biblioteki C ++, jeśli jest skompilowana w C ++.

Jeśli program jest zasadniczo taki sam, ale z dodatkowymi funkcjami, nie jest błędem stwierdzenie, że jest to ten sam program. Jest taki sam, ale także inny.

Większość programistów C potrafi przynajmniej trochę C ++ i na odwrót

Nazwanie takiej osoby programistą C / C ++ nie jest nierozsądne. Tak, prawdopodobnie specjalizują się w jednym, ale czy jest ktoś, kto jest kompetentnym programistą C lub C ++, który dosłownie nie potrafi posługiwać się żadnym innym językiem? W pewnym sensie, czy nie wszyscy oni są programistami C / C ++?

Nie ma nic złego w powiedzeniu „C / C ++”. To, co się liczy, jest rozumiane

Język angielski nie jest narzędziem do wyrażania sylogizmów . Państwo może używać języka angielskiego dla logiki, ale dopiero, iz wielkim wysiłkiem.

Wynika to z tego, że słowa nie mają w naturalny sposób dokładnego znaczenia, ale raczej niejasną chmurę denotacji i konotacji. Liczy się to, że ludzie zrozumieją to, co mówisz.


5
@ BЈовић Nie zgadzają się z tobą co do akceptowalności niewielkiej terminologii, więc wyciągasz wniosek, że nie rozumieją różnicy i są niekompetentni. To dość nieracjonalna rzecz do powiedzenia.
Ben

4
@ el.pescado Tak. Przekonasz się, że ludzie faktycznie odnoszą się do PHP / JavaScript. Dlaczego nie? Chodzi o to, aby rozumieć, nie grać w gry słowami.
Ben

10
@ BЈовић Nie masz sensu. Nie są „zupełnie inne”. C ++ jest znacznie większym językiem niż C, ale zawiera prawie całe C w nim zawarte. Istnieją niezgodności, które uniemożliwiają C ++ prawidłowy nadzbiór, ale są one małe, jak dodatkowe zastrzeżone słowa, potrzeba kilku kolejnych rzutów, ale to wszystko. Jest to prawie właściwy nadzbiór, po prostu niezupełnie.
Ben

7
@ BЈовић Być może nie rozumiesz, co napisałem. Dlaczego nie spojrzysz tutaj, aby zobaczyć, w jaki sposób w każdym przypadku można dostosować program C, aby kompilował się również jako C ++. david.tribble.com/text/cdiffs.htm#C99-vs-CPP9
Ben

7
@ BЈовић Jeśli jesteś pedantyczny wobec terminologii, powinieneś zdawać sobie sprawę, że C nie jest „ funkcjonalne ”, ale raczej „ proceduralne ” - różnicę, którą możesz chcieć zrozumieć, zanim rzucisz oskarżenia o niekompetencję na innych.
RM

15
  1. Czy powinienem przestać używać terminu C / C ++?

Absolutnie. Nie jest jasne, co ten konstrukt ma wyrazić, z wyjątkiem być może niejasności co do C i C ++ w imieniu osoby, która używa tego terminu.

Ponieważ to zamieszanie jest tak powszechnym źródłem frustracji, wiele osób zaczęło się tym bardzo przejmować, a samo pojawienie się tego terminu będzie wystarczającym powodem do negatywnego wpływu na wasz wkład. To może wydawać się głupie, ale wydaje się, że to, co mamy.

Zalecam, aby zamiast mówić o „C / C ++” używać terminu, który faktycznie wyjaśnia, co masz na myśli.

  • Jeśli mówimy o czymś w C, które mogą lub nie mogą być prawdziwe dla C ++, wystarczy powiedzieć C .

    Przykład: Jak należy mainzadeklarować funkcję w C?

    Na początku może się wydawać, że odpowiedź dla C ++ jest taka sama: int main()lub int main(int, char**). Ale w trakcie dyskusji warto zauważyć, że w C ++ funkcja musi być zadeklarowana w zakresie globalnym, co nie ma sensu w C, ponieważ nie ma namespaces. Z drugiej strony C pozwala na mainrekurencyjne wywoływanie, podczas gdy C ++ nie. W C ++ istnieje domniemanie, return 0;jeśli „spadniesz”, mainale w C returninstrukcja jest wymagana na dowolnej ścieżce. Lista jest długa i sprawia, że ​​dyskusja jest znacznie prostsza, jeśli wyraźnie wyjaśnisz, jaki język ma być omawiany.

  • Jeśli mówisz o czymś w C ++, co może, ale nie musi być prawdą dla C, po prostu powiedz C ++ .

    Przykład: czy malloc()edytowana tablica ints będzie początkowo zerami w C ++?

    Krótka odpowiedź dla C jest taka sama: nie. Ale w miarę upływu odpowiedzi warto zwrócić uwagę, że w C callocbyłaby dobrą alternatywą, podczas gdy w C ++, użycie std::vector<int>może być lepszym wyborem.

  • Jeśli chcesz wskazać podobieństwo między C i C ++, powiedz C i C ++ .

    Przykład: w C i C ++ implementacja sizeofan intjest zdefiniowana i może różnić się w zależności od kompilatora i architektury.

    W tym miejscu chcemy podkreślić, że C i C ++ zachowują się w ten sam sposób. Mówimy wyraźnie o obu językach.

Naprawdę zalecam, abyś był bardziej szczegółowy i nie mówił tylko o „C” lub „C ++”, ale o dokładnej wersji. Oba języki ewoluują, a tępe stwierdzenie, takie jak

C ++ obsługuje /* … */i // …komentarze, podczas gdy C obsługuje tylko /* … */styl.

nie jest ani dobre, ani złe.

  1. Jeśli odpowiedź na pytanie nr 1 brzmi „tak”, jak miałbym wywołać program wykorzystujący mieszankę C i C ++?

Ponieważ języki się nakładają, każdy program w C będzie zawierał części, które mogą wyglądać jak C ++ i odwrotnie. Niemniej jednak autorzy prawdopodobnie zdecydują się na użycie kompilatora C lub C ++. Powiedzmy więc, że „program jest napisany w C ”, jeśli jest skompilowany z kompilatorem C, a „program jest napisany w C ++ ”, jeśli używają kompilatora C ++, nawet jeśli mogą odmówić użycia jakichkolwiek nowoczesnych funkcji C ++. Niektórzy ludzie odnoszą się do takiego kodu C ++ jako C-stylu C ++ . Brak przeładowania, wyjątki, polimorfizm, szablony i strumienie we / wy to wspólne cechy takiego kodu.

Jeżeli natomiast niektóre pliki są zapisywane w C i skompilowany z kompilatora C i niektóre inne pliki są napisane w języku C ++ i skompilowany z kompilatora C ++, a następnie pliki obiektów połączonych ze sobą, chciałbym powiedzieć, że „program jest napisany w mix C i C ++ ”, tak jak już to zrobiłeś.

Jeśli jednak autorzy dołożyli wszelkich starań, aby napisać każdy plik w taki sposób, aby można go było skompilować za pomocą kompilatora C lub C ++, a wynikowy program zrobiłby to samo, można powiedzieć, że „program jest napisany we wspólnym podzbiorze C i C ++ ”.

To drugie często dotyczy plików nagłówkowych, które powinny być współużytkowane przez kod C i C ++. Nawiasem mówiąc, pisanie takiego kodu nie jest łatwe. Jeśli chcesz dodatkowo podkreślić, że użyto tylko takich konstrukcji, które są poprawne w C i C ++ i są szeroko obsługiwane przez różnych dostawców kompilatorów, można użyć terminu przenośny wspólny podzbiór C i C ++ .

  1. Biorąc pod uwagę, że oba są „różnymi” językami, czy jest prawdopodobne, że w pewnym momencie kompilatory C ++ przestaną obsługiwać kod napisany w języku C (ponieważ współczesne C ++ odbiega od mentalności C dla podstawowych rzeczy, takich jak wskaźniki, obsługa pamięci dynamicznej itp.)?

Nie jestem pewien, czy rozumiem to pytanie. Ponieważ C i C ++ różnymi językami, nie można oczekiwać, że kompilator dla jednego z nich zaakceptuje program napisany dla drugiego. Jednak kompilatory są często projektowane w sposób modułowy i jeśli kompilator ma interfejs C ++ , są duże szanse, że będzie miał również interfejs C. (Następnie wybierasz, który z nich chcesz za pomocą przełącznika wiersza polecenia lub podobnych środków.) Tak długo, jak oba języki będą w powszechnym użyciu, wydaje się bardzo mało prawdopodobne, że to się zmieni. Twój punkt widzenia na temat „nowoczesnego C ++” myślę, że jest to w zasadzie kwestia dobrych standardów kodowania i standardowej biblioteki. Z punktu widzenia kompilatora ewolucja obu języków jest raczej zbieżna niż rozbieżna.

  1. Czy istnieje obecnie jakaś współpraca między ludźmi, którzy tworzą standardy C / C ++ w celu zachowania zgodności?

Tak. Model pamięci i biblioteka operacji atomowych wprowadzone w C ++ 11 i C11 są dobrym przykładem. Wygląda na to, że projektanci obu języków zdają sobie sprawę, że kompatybilność jest ważna i pracują nad jej ulepszeniem. Osobiście chciałbym, aby współpraca była bardziej intensywna, a dwie grupy robocze ISO mogły nawet dołączyć, ale moje życzenia nie są ważne.

Bjarne Stroustrup mówi o różnicach i podobieństwach między różnymi wersjami C i C ++ w § 44.3 czwartej edycji języka programowania C ++, który, jak na ironię, zatytułowany jest „Kompatybilność C / C ++”. W tym przypadku użycie tego terminu może być właściwe, ponieważ jest jasne, o co chodzi.

  1. Jeśli nr 4 brzmi „tak”, taka współpraca może zakończyć się w niedalekiej przyszłości pojawieniem się nowoczesnego C ++ (11/14/17)

Jak omówiono powyżej, wydarzyło się to w C ++ 11 i oczekuje się / ma nadzieję / powinno się powtórzyć.


Jak to nie może być ani dobre, ani złe?
JDługosz

4
Nie ma dobrze zdefiniowanej wartości prawdy, jak ma to miejsce w przypadku stwierdzenia, że ​​„zielone rzeczy są drogie”. W przypadku określonej kombinacji wersji C i C ++ jest to prawda, w przypadku innych jest to fałsz.
5gon12eder

5

C / C ++ to skrzyżowanie C i C ++.

int new;nie jest C / C ++ i nie jest vector<int> foo;.

Podobnie C89 / C99 to skrzyżowanie tych dwóch języków, w których żaden enum bool { false, true };lub nie for(int i = 0;;)jest dozwolony.

I C ++ 11 / C ++ 14 itd.

Możliwe jest pisanie kodu, który kompiluje (i poprawnie działa) w C ++ 11 i C ++ 14, nawet jeśli kompilacja pod jednym nie oznacza, że ​​kompiluje się pod drugim. W rzeczywistości robi to wiele osób.

I wiele osób pisze kod, który działa w C i C ++.

Oczywiście im większe nakładanie się, tym bardziej sensowne; Nie oczekuję żadnych pytań dotyczących kodu C / C ++ / Java.


Chociaż „sensowne” jest mówienie o wspólnym podzbiorze tych języków, wiele pytań nie będzie zawierało odpowiedzi w tym podzbiorze, np. Co powinien zwrócić main () w C i C ++?

Ale możesz mówić o kodzie, który działa dla specyfikacji wielu języków, bez względu na to, czy specyfikacje te są rozróżniane według „wersji” lub „nazwy języka”, czy w inny sposób.


3

Jest to swego rodzaju odpowiedź na stanowisko, że „jest to kod dla programistów, którzy pracują blisko metalu i są OK w kontekście zarządzania”, co widać w innych odpowiedziach i komentarzach.


Twierdziłbym, że nawet przy takiej interpretacji należy zachować ostrożność.

Począwszy od połowy lat 90., jeśli chciałeś programisty C ++ i kogoś, kto opisał się jako programista C, musiałbyś zapytać, ile wiedzą o projektowaniu obiektowym, ile mają doświadczenia w debugowaniu obiektu zorientowany kontekst oraz ich zdolność do korzystania z bibliotek szablonów. Chcesz dokładnie zbadać te problemy podczas rozmowy kwalifikacyjnej i procesu rekrutacji.

Z drugiej strony minęło ponad dziesięć lat, odkąd guru C ++ zaczęli pchać „nowoczesne C ++”, co oznacza nacisk na odejście od odsłoniętych wskaźników do bezpieczniejszych obiektów wskaźnikowych i idiomów opartych na iteratorze. Wraz z pojawieniem się C ++ 11 istnieje teraz wyraźne wsparcie dla programowania z wieloma paradygmatami, a nacisk na kod, który nie wykazuje żadnych wyraźnych wskaźników, jest bardzo silny. Oznacza to, że gdybym dzisiaj przeprowadził wywiad z programistą C ++ na stanowisku C, bardzo martwi mnie sprawdzenie, czy ta osoba była zaznajomiona z rzeczywistymi wskazówkami umożliwiającymi strzelanie stopą.

Obecnie nie jestem w branży (nawet w takim stopniu, w jakim byłem wtedy, gdy Stack Overflow był w powijakach), więc nie odważę się zgadywać, jak często któryś z wyimaginowanych rozmówców nie miałby umiejętności przejścia, ale Myślę, że jak najczęściej stosowane języki są teraz bardzo różne.

Krótko mówiąc, „C / C ++” należy porzucić nie tylko w kontekstach technicznych, ale także w większości kontekstów biznesowych.


Dobry sposób na wskazanie, że dwuznaczność tego, czy oznacza to „albo C albo C ++, kto wie”, „C i C ++, połączone razem”, „C i C ++, skrzyżowanie” lub „C lub C ++, kogo to obchodzi” jest coraz mniej uzasadnione, nawet jeśli można to jakoś uniknąć.
Deduplicator

2

Najprostszą odpowiedzią na to pytanie jest to, że nigdy nie powinieneś używać tego terminu. Jest to termin, który nie powinien istnieć. To nie ma znaczenia. Każdy program to C lub C ++.

I tak było cicho, aż do pojawienia się C ++ x0, C ++ 11 (lub ogólnie C ++ 11/14/17).

C ++ 98 i 03 nie są nawet zdalnie C w klasach. Ktokolwiek cię tego nauczył, nie zna gówna i możesz o nich zapomnieć. To nigdy nie było poprawne.


To nie do końca prawda. Była kiedyś strona opisująca proponowaną specyfikację języka dla języka o nazwie „C / C ++”, który między innymi określał (prawie) brak systemu typów. Niestety strona została już usunięta, a witryna, która ją hostowała, opublikowała plik robots.txt, który usunął zarchiwizowaną kopię z archive.org.
greyfade

1
Aha, znalazłem kopię na archive.is: uzasadnienie , składnia i semantyka .
greyfade

5
„Każdy program to C lub C ++.” Nie zgadzam się. Często zdarza się, że bierzemy program C i przenosimy go do C ++ jeden plik na raz (zmieniając opcję kompilatora dla tego jednego pliku). Niektóre pliki mogą nigdy nie zostać przeniesione i pozostaną na zawsze C. Taki program jest napisany zarówno w C, jak i C ++
nikie

Nie całkiem. Ten program składa się z podprogramów, z których każdy to C lub C ++. Każda JT, która jest całym programem, jeśli chodzi o kompilator, jest kompilowana jako C lub C ++.
DeadMG

3
To nie jest tak, że „Każdy program to C lub C ++”. Prof. Bjarne Stroustrup mówi: „Dobrze napisane C zwykle jest również legalnym C ++. Na przykład każdy przykład w Kernighan & Ritchie: „The C Programming Language (2nd Edition)” to także program w C ++. ” stroustrup.com/bs_faq.html#C-is-subset
Ben

1

Koncepcyjnie, nie powinno być żadnych szczególnych trudności w projektowaniu plików źródłowych w języku C, aby można je było kompilować bez zmian w C ++. Rzeczywiście może to mieć pewne znaczące zalety. Na przykład podczas pisania kodu dla systemu osadzonego czasami pomocne jest przetestowanie kodu na hostowanym środowisku PC. Jeśli kod skompiluje się czysto jako C ++, możliwe jest wyrażenie takie jak „MOTOR_ENABLE = 1;” zapisz do lotnego bitu I / O we wbudowanym systemie (skompilowanym jako C), ale uruchom logikę emulacji na komputerze PC (kompilowanym jako C ++). Prawdopodobnie byłoby również możliwe zaprojektowanie na komputerze typu C ++, który zachowywałby się tak, jak uint16_t zachowuje się w mniejszych systemach wbudowanych (tak, że np. Biorąc pod uwagę u16 x=65533;, kompilator musiałby uwzględniać wartośćx*xjako dziewięć, zamiast mieć swobodę panowania nad wszystkim, co chce), chociaż jak dotąd żaden z moich emulatorów tego nie uwzględnił [częściowo dlatego, że kompilatory C ++, których użyłem, nie zrobiły nic zwariowanego w takich przypadkach].

Niestety, programiści C i programiści C ++ mają wystarczającą niechęć do siebie nawzajem, że języki przez lata ewoluowały w kompatybilny sposób. Podczas gdy C89 próbował dostosować niektóre bardziej użyteczne funkcje C ++ (takie jak prototypy funkcji), wydaje się, że pojawiła się postawa, że ​​programiści, którzy chcą którejkolwiek z funkcji C ++, powinni używać C ++, ignorując fakt, że istnieje wiele sytuacji, w których być pomocnym, aby móc korzystać z niektórych funkcji C ++ (np. zdolność do przeciążania funkcji statycznym lub statycznym łączeniem wbudowanym bez konieczności ponoszenia kosztów związanych z innymi funkcjami, których się nie potrzebuje (np. zmiana nazwy związana z eksportem przeciążone funkcje).

Podczas gdy przecięcie C89 i C ++ 98 jest praktycznym językiem, użyteczny nadzbiór późniejszych wersji C z późniejszymi wersjami C ++ prawdopodobnie raczej się skurczył niż rozwinął (dzięki takim rzeczom, jak reguła ścisłego aliasowania), a trendy sprzyjają zawsze narastająca szczelina.


1
Co to jest „C ++ 95”? Raport techniczny?
Ben Voigt

1
Jeśli chcesz przeciążać funkcje wewnętrzne, ale nie zmieniać nazwy dla funkcji zewnętrznych, możesz ustawić to pierwsze na anonimowe namespacei zadeklarować drugie jako extern "C", a następnie użyć kompilatora C ++.
5gon12eder

@BenVoigt: Mea culpa. Powinienem to sprawdzić. Wersja C ++ przed C99. Kiedy pojawiło się C89, próbował uczynić C bardziej podobnym do C ++, ale C99 dodał sporo funkcji, którymi C ++ zdecydowanie nie był zainteresowany (np. Tablice o zmiennej długości). Nie programuję dużo w C ++, ale myślę, że kilka dodatkowych funkcji C ++ pomogłoby C bardziej niż rozbieżne funkcje pomogły.
supercat

@ 5gon12eder: Nigdy nie próbowałem łączyć kodu C ++ z projektem C. Czy to naprawdę tak proste, jak mieć wszystko albo statyczne / wbudowane, czy extern "C"też są też inne komplikacje (np. Inicjalizacja obiektu statycznego itp.)? Czy jest jakiś sposób w C ++, aby uczynić go tak, foo(1234)aby wywoływał foo_const(1234)makro, podczas gdy foo(x)[gdzie xnie jest stałą] wywoła foo_var(x)funkcję? Istnieje wiele sytuacji, w których osadzone w kodzie może mieć sens dla „funkcja” Lubię SET_PORT(port, state)mieć trzy formy oparciu czy portu i państwo są zarówno ...
SuperCat

... stałe czasu kompilacji, port jest stały, ale stan nie, lub gdzie ani port, ani stan nie są stałymi. Czy jest jakiś sposób, aby to osiągnąć za pomocą szablonów lub innego standardowego mechanizmu C ++, czy jest to możliwe tylko w kompilatorach z rozszerzeniami gcc?
supercat
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.