что Где C не подмножество C++?




что такое title и description (10)

Я читал во многих книгах, что C - подмножество C ++.

В некоторых книгах говорится, что C является подмножеством C ++, за исключением небольших деталей .

Каковы некоторые случаи, когда код будет компилироваться в C, но не C ++?


#include <stdio.h>

int new (int n) {
    return n/2;
}

int main(void) {
    printf("%d\n", new(10));
    return 0;
}

См. Также раздел C ++ FAQ .


Есть много вещей. Просто простой пример (этого должно быть достаточно, чтобы доказать, что C не является надлежащим подмножеством C ++):

int* test = malloc(100 * sizeof(int));

должен компилироваться в C, но не на C ++.


Ряд ответов здесь содержит различия в синтаксисе, которые могут привести к сбою компиляторов C ++ в исходном коде C89 (или C99). Однако существуют некоторые тонкие языковые различия, которые являются законными на обоих языках, но это может привести к поведению. Разница sizeof (char) , упомянутая Навееном, является одним из примеров, но напишите программу, которая будет печатать «C», если она скомпилирована как программа (ANSI) C, а «C ++», если она скомпилирована как программа на C ++, перечисляет некоторые другие.


В C ++, если вы объявляете struct , union или enum , его имя сразу же доступно без каких-либо квалификаторов:

struct foo { ... };
foo x; // declare variable

В C это не будет работать, потому что типы, объявленные таким образом, живут в своих собственных пространствах имен. Таким образом, вы должны написать:

struct foo { ... };
struct foo x; // declare variable

Обратите внимание на наличие struct на второй строке. Вы должны сделать то же самое для union и enum (используя их соответствующие ключевые слова) или использовать трюк typedef :

typedef struct { ... } foo;
foo x; // declare variable

Следовательно, вы можете иметь несколько типов разных типов, названных одинаковыми в C, поскольку вы можете устранить неоднозначность:

struct foo { ... };
typedef enum { ... } foo;

struct foo x;
foo y;

Однако на C ++, хотя вы можете префиксное имя struct с помощью struct когда вы ссылаетесь на нее, пространства имен объединяются, поэтому приведенный выше фрагмент кода C недействителен. С другой стороны, C ++ специально делает исключение, чтобы тип и typedef для этого типа имели одно и то же имя (очевидно, без эффекта), чтобы использовать трюк typedef без изменений от C.


Компиляторы C обычно допускали небольшую угловую резку, что C ++ не делает. C ++ гораздо более строг, чем C. И, как правило, некоторые из этих различий зависят от компилятора. g ++ позволяет, например, некоторые вещи, которые компилятор Intel C ++ не делает. Даже довольно хорошо написанный код C не будет компилироваться с помощью современного компилятора C ++.


Если вы сравните C89 с C++ то вот пара вещей

Никаких предварительных определений в C ++

int n;
int n; // ill-formed: n already defined

int [] и int [N] несовместимы (нет совместимых типов в C ++)

int a[1];
int (*ap)[] = &a; // ill-formed: a does not have type int[]

Нет стиля определения функции K & R

int b(a) int a; { } // ill-formed: grammar error

Вложенная структура имеет класс-область в C ++

struct A { struct B { int a; } b; int c; };
struct B b; // ill-formed: b has incomplete type (*not* A::B)

Нет значения по умолчанию int

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);

Вы не можете сравнивать языки только по синтаксису. Если вы это сделаете, возможно, вы можете увидеть C как подмножество C ++. На мой взгляд, того факта, что C ++ является OO (и C не является), достаточно, чтобы сказать, что C и C ++ - разные языки.


В C sizeof('a') равен sizeof(int) .

В C ++ sizeof('a') равен sizeof(char) .


Это также зависит от того, какое разнообразие вы используете. Stroustrup сделал C ++ настолько совместимым, насколько он мог, и не более совместим с 1989 стандартами ANSI и 1990 ISO, а версия 1995 года ничего не изменила. Комитет С пошел в несколько другом направлении со стандартом 1999 года, и комитет C ++ изменил следующий стандарт C ++ (возможно, в следующем году или около того), чтобы соответствовать некоторым изменениям.

Stroustrup перечисляет несовместимости с C90 / C95 в Приложении B.2 «Язык программирования C ++», Special Edition (который является третьим изданием с некоторыми дополнительными материалами):

'a' - это int в C, char в C ++.

Размер перечисления - int в C, не обязательно в C ++.

C ++ имеет // комментарии к концу строки, C не (хотя это общее расширение).

В C ++ struct foo { definition помещает 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 d в стандартных заголовках C.

Есть также некоторые более старые функции C, которые больше не считаются хорошим стилем. В C вы можете объявить функцию с определениями аргументов после списка аргументов. В C объявление типа int foo() означает, что foo() может принимать любое количество аргументов любого типа, тогда как в C ++ оно эквивалентно int foo(void) .

Кажется, это все охватывает от Страуструпа.


У C ++ есть и новые ключевые слова. Ниже приведен допустимый код C, но он не будет компилироваться под C ++:

int class = 1;
int private = 2;
int public = 3;
int virtual = 4;




c