Czytałem w wielu książkach, że C jest podzbiorem C ++.
Niektóre książki mówią, że C jest podzbiorem C ++, z wyjątkiem drobnych szczegółów .
Jakie są przypadki, gdy kod będzie kompilowany w C, ale nie w C ++?
Jeśli porównasz C89
z, C++
oto kilka rzeczy
int n;
int n; // ill-formed: n already defined
int a[1];
int (*ap)[] = &a; // ill-formed: a does not have type int[]
int b(a) int a; { } // ill-formed: grammar error
struct A { struct B { int a; } b; int c; };
struct B b; // ill-formed: b has incomplete type (*not* A::B)
auto a; // ill-formed: type-specifier missing
C99 dodaje całą masę innych przypadków
// ill-formed: invalid syntax
void f(int p[static 100]) { }
// ill-formed: n is not a constant expression
int n = 1;
int an[n];
// ill-formed: fam has incomplete type
struct A { int a; int fam[]; };
// ill-formed: two names for one parameter?
void copy(int *restrict src, int *restrict dst);
typedef;
to legalna jednostka TU w C, ale nie w C ++.auto a;
obowiązuje w najnowszej wersji standardu C ++.a
?auto x;
nie obowiązuje w najnowszej wersji, ale na przykładauto x = 0;
jest. Na początku byłem trochę zszokowany :)W C
sizeof('a')
jest równesizeof(int)
.W C ++
sizeof('a')
jest równesizeof(char)
.źródło
'a'
jestint
. W C ++'a'
to plikchar
.C ++ ma również nowe słowa kluczowe. Poniższy kod jest prawidłowym kodem w C, ale nie kompiluje się w C ++:
źródło
Jest mnóstwo rzeczy. Prosty przykład (wystarczy udowodnić, że C nie jest odpowiednim podzbiorem C ++):
powinien kompilować się w C, ale nie w C ++.
źródło
int*
.void *
, które w C można przypisać do dowolnego typu wskaźnika, a C ++ nie może być przypisane do żadnego innego typu wskaźnika.W C ++, jeśli zadeklarujesz a
struct
,union
lubenum
, jego nazwa jest natychmiast dostępna bez żadnych kwalifikatorów:W C to nie zadziała, ponieważ zadeklarowane w ten sposób typy żyją w swoich własnych odrębnych przestrzeniach nazw. Musisz więc napisać:
Zwróć uwagę na obecność
struct
tam w drugiej linii. Musisz zrobić to samo dlaunion
ienum
(używając odpowiednich słów kluczowych) lub użyćtypedef
sztuczki:W związku z tym możesz mieć kilka typów różnych rodzajów nazwanych tak samo w C, ponieważ możesz ujednoznacznić:
Jednak w C ++, chociaż możesz poprzedzić
struct
nazwę słowem kluczowymstruct
za każdym razem, gdy się do niej odwołujesz, przestrzenie nazw są scalane, więc powyższy fragment C jest nieprawidłowy. Z drugiej strony, C ++ robi wyjątek, aby pozwolić typowi i definicji typu dla tego typu mieć tę samą nazwę (oczywiście bez efektu), aby umożliwić użycietypedef
triku niezmienionego od C.źródło
struct
,union
ienum
) udział ten sam nazw. Lepszym przykładem może byćstruct foo { ... }; typedef enum { ... } foo;
Zależy to również od używanej odmiany C. Stroustrup uczynił C ++ tak kompatybilnym, jak tylko mógł, a nie bardziej kompatybilnym, z normami ISO 1989 ANSI i 1990, a wersja 1995 niczego nie zmieniła. Komisja C poszła w nieco innym kierunku ze standardem 1999, a komisja C ++ zmieniła następny standard C ++ (prawdopodobnie w przyszłym roku), aby dostosować się do niektórych zmian.
Stroustrup wymienia niezgodności z C90 / C95 w Dodatku B.2 „Języka programowania C ++”, wydanie specjalne (czyli wydanie trzecie z dodatkowymi materiałami):
'a'
jestint
w C, achar
w C ++.Rozmiar wyliczenia to
int
w C, niekoniecznie w C ++.C ++ ma
//
komentarze na końcu linii, C nie (chociaż jest to powszechne rozszerzenie).W C ++
struct foo {
definicja umieszczana jestfoo
w globalnej przestrzeni nazw, podczas gdy w C musiałaby być nazywanastruct foo
. Pozwala tostruct
definicji przesłonić nazwę w zakresie zewnętrznym i ma kilka innych konsekwencji. Ponadto C umożliwia większy zakresstruct
definicji i zezwala na ich deklaracje typu zwracanego i typu argumentu.C ++ jest ogólnie bardziej zawstydzony co do typów. Nie pozwoli na przypisanie liczby całkowitej do obiektu
enum
, avoid *
obiekty nie mogą być przypisane do innych typów wskaźników bez rzutowania. W C można podać zbyt duży inicjator (char name[5] = "David"
gdzie C odrzuci końcowy znak null).C89 jest dozwolone
int
w wielu kontekstach, a C ++ nie. Oznacza to, że wszystkie funkcje muszą być zadeklarowane w C ++, podczas gdy w C89 często można było załatwićint
wszystko, co ma zastosowanie w deklaracji funkcji.W C można przeskoczyć z zewnątrz bloku do wewnątrz za pomocą instrukcji z etykietą. W C ++ nie jest to dozwolone, jeśli pomija inicjalizację.
C jest bardziej liberalny w połączeniach zewnętrznych. W C
const
zmienna globalna jest niejawnieextern
, aw C ++ to nieprawda. C pozwala na kilkakrotne zadeklarowanie globalnego obiektu danych bez znakuextern
, ale nie jest to prawdą w C ++.Wiele słów kluczowych w języku C ++ nie jest słowami kluczowymi w języku C lub występuje
#define
w standardowych nagłówkach C.Istnieją również starsze funkcje C, które nie są już uważane za dobry styl. W C możesz zadeklarować funkcję z definicjami argumentów po liście argumentów. W C deklaracja taka jak
int foo()
oznacza, którafoo()
może przyjąć dowolną liczbę argumentów dowolnego typu, podczas gdy w C ++ jest to odpowiednikint foo(void)
.Wydaje się, że obejmuje wszystko od Stroustrup.
źródło
Jeśli używasz gcc, możesz użyć ostrzeżenia
-Wc++-compat
do ostrzeżenia o kodzie w C, który jest w jakiś sposób wątpliwy w C ++. Obecnie jest używany w samym gcc, a ostatnio stał się znacznie lepszy (może spróbuj nocnej wersji, aby uzyskać najlepsze możliwe).(To nie jest dokładną odpowiedzią na pytanie, ale ludziom może się to podobać).
źródło
Myślę, że największą różnicą jest to, że jest to prawidłowy plik źródłowy w języku C:
Zauważ, że nie zadeklarowałem
foo
nigdzie .Oprócz różnic językowych, C ++ wprowadza również pewne zmiany w bibliotece, którą odziedziczył po C, np. Niektóre funkcje zwracają
const char *
zamiastchar *
.źródło
s,C,C89,
i zauważyć, że jest to nieprawidłowy plik źródłowy C99.Zobacz także wpis C ++ FAQ .
źródło
Szereg odpowiedzi tutaj dotyczy różnic w składni, które mogą spowodować niepowodzenie kompilatorów C ++ w kodzie źródłowym C89 (lub C99). Istnieją jednak pewne subtelne różnice językowe, które są legalne w obu językach, ale skutkują różnymi zachowaniami.
sizeof (char)
Różnicą, że Naveen wspomniano jest jednym z przykładów, ale Napisz program, który będzie drukować „C”, jeśli skompilowany jako (ANSI) C programu, a „C ++” czy kompilowany jako C ++ programu list inni.źródło
Kompilatory C generalnie pozwalały na małe cięcie narożników, czego C ++ nie robi. C ++ jest dużo bardziej rygorystyczny niż C. I ogólnie, niektóre z tych różnic są zależne od kompilatora. g ++ pozwala na pewne rzeczy, na przykład kompilator Intel C ++. Nawet całkiem dobrze napisany kod w C nie da się skompilować za pomocą nowoczesnego kompilatora C ++.
źródło
Nie można porównywać języków tylko za pomocą składni. Jeśli to zrobisz, być może zobaczysz C jako podzbiór C ++. Moim zdaniem fakt, że C ++ to OO (a C nie jest) wystarczy, aby powiedzieć, że C i C ++ to różne języki.
źródło