Joh*_*itb 133
如果你比较C89有C++那么这里有几件事情
int n;
int n; // ill-formed: n already defined
Run Code Online (Sandbox Code Playgroud)
int a[1];
int (*ap)[] = &a; // ill-formed: a does not have type int[]
Run Code Online (Sandbox Code Playgroud)
int b(a) int a; { } // ill-formed: grammar error
Run Code Online (Sandbox Code Playgroud)
struct A { struct B { int a; } b; int c; };
struct B b; // ill-formed: b has incomplete type (*not* A::B)
Run Code Online (Sandbox Code Playgroud)
auto a; // ill-formed: type-specifier missing
Run Code Online (Sandbox Code Playgroud)
C99增加了很多其他案例
// ill-formed: invalid syntax
void f(int p[static 100]) { }
Run Code Online (Sandbox Code Playgroud)
// ill-formed: n is not a constant expression
int n = 1;
int an[n];
Run Code Online (Sandbox Code Playgroud)
// ill-formed: fam has incomplete type
struct A { int a; int fam[]; };
Run Code Online (Sandbox Code Playgroud)
// ill-formed: two names for one parameter?
void copy(int *restrict src, int *restrict dst);
Run Code Online (Sandbox Code Playgroud)
Nav*_*een 48
在C中,sizeof('a')等于sizeof(int).
在C++中,sizeof('a')等于sizeof(char).
Gra*_*row 36
C++也有新的关键字.以下是有效的C代码,但不会在C++下编译:
int class = 1;
int private = 2;
int public = 3;
int virtual = 4;
Run Code Online (Sandbox Code Playgroud)
Meh*_*ari 20
有很多东西.只是一个简单的例子(它应该足以证明C不是C++的适当子集):
int* test = malloc(100 * sizeof(int));
Run Code Online (Sandbox Code Playgroud)
应该用C编译而不是用C++编译.
Pav*_*aev 16
在C++中,如果声明一个struct,union或enum,它的名称可以立即访问,而不需要任何限定符:
struct foo { ... };
foo x; // declare variable
Run Code Online (Sandbox Code Playgroud)
在C中,这将不起作用,因为这样声明的类型存在于它们自己的不同命名空间中.因此,你必须写:
struct foo { ... };
struct foo x; // declare variable
Run Code Online (Sandbox Code Playgroud)
注意struct第二行是否存在.你必须为(union和enum使用他们各自的关键字)做同样的事情,或使用typedef技巧:
typedef struct { ... } foo;
foo x; // declare variable
Run Code Online (Sandbox Code Playgroud)
因此,您可以在C中将几种类型的不同类型命名为相同,因为您可以消除歧义:
struct foo { ... };
typedef enum { ... } foo;
struct foo x;
foo y;
Run Code Online (Sandbox Code Playgroud)
但是,在C++中,虽然您可以在引用时struct使用关键字为名称添加前缀,但是struct命名空间会合并,因此上面的C片段无效.另一方面,C++特别提出异常,允许该类型的类型和typedef具有相同的名称(显然没有效果),允许使用typedefC中未更改的技巧.
这还取决于您使用的C种类.Stroustrup使得C++尽可能兼容,并且与1989 ANSI和1990 ISO标准不相容,而且1995版没有改变.C委员会与1999标准的方向略有不同,C++委员会已经改变了下一个C++标准(可能在明年左右),以符合一些变化.
Stroustrup列出了"C++编程语言"特别版附录B.2中与C90/C95的不兼容性(第3版附带了一些附加材料):
'a'是一个intC,一个char在C++中.
枚举的大小int在C中,不一定在C++中.
C++ //对行尾有注释,C没有(虽然它是常见的扩展).
在C++中,struct foo {定义放入foo全局命名空间,而在C中则必须将其称为struct foo.这允许struct定义在外部作用域中隐藏名称,并具有一些其他后果.此外,C允许更大的struct定义范围,并允许它们返回类型和参数类型声明.
一般来说,C++对类型更加苛刻.它不允许将整数分配给an enum,并且void *在没有强制转换的情况下不能将对象分配给其他指针类型.在C中,可以提供一个过大的初始值设定项(char name[5] = "David"其中C将丢弃尾随的空字符).
C89允许int在许多上下文中隐含,而C++则不允许.这意味着所有函数都必须在C++中声明,而在C89中,通常可以假设int函数声明中适用的所有内容.
在C中,可以使用带标签的语句从块外部跳转到内部.在C++中,如果它跳过初始化,则不允许这样做.
C在外部联系方面更加自由.在C中,一个全局const变量是隐式的extern,而在C++中则不然.C允许在没有a的情况下多次声明全局数据对象extern,但在C++中则不然.
许多C++关键字不是C中的关键字,或者是#define标准C头中的关键字.
还有一些C的旧功能不再被认为是好的风格.在C中,您可以在参数列表后面声明一个带有参数定义的函数.在C中,像一个声明int foo()该装置foo()可以采取任何数量的任何类型的参数,而在C++中它相当于int foo(void).
这似乎涵盖了Stroustrup的所有内容.
如果您使用 gcc,您可以使用警告-Wc++-compat向您发出有关 C 代码的警告,这些代码在 C++ 中以某种方式是可疑的。它目前在 gcc 本身中使用,并且最近变得更好(也许尝试每晚版本以获得最佳效果)。
(这并不能严格回答问题,但人们可能会喜欢它)。
#include <stdio.h>
int new (int n) {
return n/2;
}
int main(void) {
printf("%d\n", new(10));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
另请参阅C++ 常见问题解答条目。
我认为最大的区别是这是一个有效的 C 源文件:
int main()
{
foo();
}
Run Code Online (Sandbox Code Playgroud)
请注意,我没有foo在任何地方声明。
除了语言差异之外,C++ 还对其从 C 继承的库进行了一些更改,例如,某些函数返回const char *而不是char *.