Я читал во многих книгах, что C - это подмножество C ++.
В некоторых книгах говорится, что C - это подмножество C ++, за исключением мелких деталей .
В каких случаях код компилируется на C, но не на C ++?
Если сравнить C89
с, C++
то вот пара вещей
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 добавляет много других случаев
// 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;
это законный TU в C, но не в C ++.auto a;
это действительно в последней версии стандарта C ++.a
?auto x;
не действует в последней версии, но, напримерauto x = 0;
, так. Сначала я был немного шокирован :)В языке C
sizeof('a')
равноsizeof(int)
.В C ++
sizeof('a')
равноsizeof(char)
.источник
'a'
- это файлint
. В C ++'a'
это файлchar
.В C ++ также есть новые ключевые слова. Ниже приведен допустимый код C, но он не будет компилироваться под C ++:
источник
Есть много чего. Просто простой пример (этого должно быть достаточно, чтобы доказать, что C не является правильным подмножеством C ++):
должен компилироваться на C, но не на C ++.
источник
int*
.void *
, который в C может быть назначен любому типу указателя, а C ++ не может быть назначен любому другому типу указателя.В C ++, если вы объявляете
struct
,union
илиenum
его имя сразу же доступны без каких - либо классификаторов:В C это не сработает, потому что объявленные таким образом типы живут в своих собственных отдельных пространствах имен. Таким образом, вы должны написать:
Обратите внимание на присутствие
struct
там во второй строке. Вы должны сделать то же самое дляunion
иenum
(используя соответствующие ключевые слова) или использоватьtypedef
уловкой:Следовательно, у вас может быть несколько типов разных видов, названных одинаково в C, поскольку вы можете устранить неоднозначность:
В C ++, однако, хотя вы можете префикс
struct
имени с ключевым словомstruct
всякий раз, когда вы на него ссылаетесь, пространства имен объединяются, и поэтому приведенный выше фрагмент C недействителен. С другой стороны, C ++ специально делает исключение, позволяющее типу и typedef для этого типа иметь одно и то же имя (очевидно, без эффекта), чтобы разрешить использованиеtypedef
трюка без изменений по сравнению с C.источник
struct
,union
иenum
) используют одно и то же пространство имен. Лучшим примером может бытьstruct foo { ... }; typedef enum { ... } foo;
Это также зависит от того, какую разновидность C вы используете. Страуструп сделал C ++ максимально совместимым и не более совместимым со стандартами ANSI 1989 и ISO 1990, и версия 1995 года ничего не изменила. Комитет C пошел в несколько ином направлении со стандартом 1999 года, а комитет C ++ изменил следующий стандарт C ++ (вероятно, в следующем году или около того), чтобы соответствовать некоторым изменениям.
Страуструп перечисляет несовместимость с C90 / C95 в Приложении B.2 «Язык программирования C ++», Special Edition (это 3-е издание с некоторыми добавленными материалами):
'a'
являетсяint
в C, achar
в C ++.Размер перечисления находится
int
в C, не обязательно в C ++.C ++ имеет
//
комментарии до конца строки, в C - нет (хотя это обычное расширение).В C ++
struct foo {
определение помещаетсяfoo
в глобальное пространство имен, а в C оно должно называтьсяstruct foo
. Это позволяетstruct
определению скрывать имя во внешней области видимости и имеет несколько других последствий. Кроме того, C допускает более широкие возможности дляstruct
определений и позволяет использовать их в объявлениях типа возвращаемого значения и типа аргумента.В C ++ больше внимания уделяется типам в целом. Это не позволит присвоить целое число
enum
, иvoid *
объекты нельзя назначать другим типам указателей без приведения. В C можно предоставить слишком большой инициализатор (char name[5] = "David"
где C отбросит завершающий нулевой символ).C89 разрешен неявным образом
int
во многих контекстах, а C ++ - нет. Это означает, что все функции должны быть объявлены на C ++, тогда как в C89 часто можно было обойтись, предполагаяint
все, что применимо в объявлении функции.В C можно переходить из-за пределов блока внутрь, используя помеченный оператор. В C ++ это запрещено, если он пропускает инициализацию.
C более либерален во внешних связях. В C глобальный
const
переменная неявно используетсяextern
, а в C ++ это неверно. C позволяет несколько раз объявлять глобальный объект данных безextern
, но это не так в C ++.Многие ключевые слова C ++ не являются ключевыми словами в C или содержатся
#define
в стандартных заголовках C.Есть также некоторые старые особенности C, которые больше не считаются хорошим стилем. В C вы можете объявить функцию с определениями аргументов после списка аргументов. В C такое объявление
int foo()
означает, чтоfoo()
может принимать любое количество аргументов любого типа, а в C ++ оно эквивалентноint foo(void)
.Похоже, это касается всего, что касается Страуструпа.
источник
Если вы используете gcc, вы можете использовать предупреждение
-Wc++-compat
чтобы выдать вам предупреждения о коде C, который в некотором роде сомнителен в C ++. В настоящее время он используется в самом gcc, и в последнее время он стал намного лучше (возможно, попробуйте ночную версию, чтобы получить лучшее, что вы можете).(Это не совсем ответ на вопрос, но людям это может понравиться).
источник
Единственное самое большое отличие, я думаю, заключается в том, что это действительный исходный файл на C:
Обратите внимание, что я
foo
нигде не заявлял .Помимо языковых различий, C ++ также вносит некоторые изменения в библиотеку, унаследованную от C, например, некоторые функции возвращают
const char *
вместоchar *
.источник
s,C,C89,
и отметить, что это недопустимый исходный файл C99.См. Также раздел часто задаваемых вопросов по C ++ .
источник
Ряд ответов здесь касается различий в синтаксисе, которые могут привести к сбою компиляторов C ++ в исходном коде C89 (или C99). Однако есть некоторые тонкие языковые различия, которые допустимы для обоих языков, но могут привести к разному поведению.
sizeof (char)
Разница , что Навин упоминается один из примеров, но написать программу , которая будет печатать «C» , если скомпилирован как (ANSI) C программы, и «C ++» , если скомпилирован как ++ программ C перечислены некоторые другие.источник
Компиляторы C обычно допускали небольшую обрезку углов, в отличие от C ++. C ++ намного строже, чем C. И, как правило, некоторые из этих различий зависят от компилятора. g ++ допускает некоторые вещи, которые, например, не позволяет компилятору Intel C ++. Даже хорошо написанный код C не будет компилироваться с современным компилятором C ++.
источник
Вы не можете сравнивать языки только по синтаксису. Если вы это сделаете, возможно, вы увидите C как подмножество C ++. На мой взгляд, того факта, что C ++ - объектно ориентированный (а C - нет), достаточно, чтобы сказать, что C и C ++ - разные языки.
источник