在C和C+中都有效的Can代码+;在每种语言中编译时产生不同的行为? C和C++有很多不同之处,并不是所有的有效C代码都是有效的C++代码。 (所谓“有效”是指具有已定义行为的标准代码,即非特定于实现/未定义/等) 有没有一种情况,在C语言和C++语言中,当用标准语言编译时,C语言和C++语言中的代码会产生不同的行为?
为了使之成为一个合理/有用的比较(我试图学习一些实际有用的东西,而不是试图找出问题中明显的漏洞),让我们假设:在C和C+中都有效的Can代码+;在每种语言中编译时产生不同的行为? C和C++有很多不同之处,并不是所有的有效C代码都是有效的C++代码。 (所谓“有效”是指具有已定义行为的标准代码,即非特定于实现/未定义/等) 有没有一种情况,在C语言和C++语言中,当用标准语言编译时,C语言和C++语言中的代码会产生不同的行为?,c++,c,C++,C,为了使之成为一个合理/有用的比较(我试图学习一些实际有用的东西,而不是试图找出问题中明显的漏洞),让我们假设: 与预处理器无关(这意味着没有对\ifdef\uu cplusplus、pragmas等的攻击) 在两种语言中定义的任何实现都是相同的(例如,数字限制等) 我们正在比较每个标准的合理最新版本(例如,C++98和C90或更高版本) 如果版本很重要,那么请说明每个版本的哪些版本会产生不同的行为 #包括 内部主(空) { printf(“%d\n”,(int)sizeof('a'); 返回0
- 与预处理器无关(这意味着没有对
、pragmas等的攻击)\ifdef\uu cplusplus
- 在两种语言中定义的任何实现都是相同的(例如,数字限制等)
- 我们正在比较每个标准的合理最新版本(例如,C++98和C90或更高版本)
如果版本很重要,那么请说明每个版本的哪些版本会产生不同的行为
#包括
内部主(空)
{
printf(“%d\n”,(int)sizeof('a');
返回0;
}
在C语言中,无论当前系统上的sizeof(int)
值是多少,它都会打印出来,这在当今大多数常用的系统中通常是4
<>在C++中,必须打印1 .< /p> < p>一个依赖于C编译器的老板栗,而不是识别C++结尾的注释……/P>
...
int a = 4 //* */ 2
+2;
printf("%i\n",a);
...
C++编程语言(第三版)给出三个例子:
int f(int a, int b)
{
return a //* blah */ b
;
}
返回代码为0,C++为3,C.</P>为返回 这个技巧可能可以用来做一些更有趣的事情,但我想不出一个好的方法来创建一个C喜欢的构造函数。我尝试用复制构造函数制作一个类似的枯燥示例,这样可以传递一个参数,尽管是以一种不可移植的方式:
struct exit
{
int x;
};
int main()
{
struct exit code;
code.x=1;
exit(code);
return 0;
}
VC++ 2005拒绝编译C++模式,而是抱怨如何重新定义“退出代码”。(我认为这是一个编译器错误,除非我突然忘记如何编程)它在C编译时退出了1的进程退出代码。
< P> C++标准列出的另一个:#include <stdio.h>
int x[1];
int main(void) {
struct x { int a[2]; };
/* size of the array in C */
/* size of the struct in C++ */
printf("%d\n", (int)sizeof(x));
}
#包括
int x[1];
内部主(空){
结构x{inta[2];};
/*数组的大小(以C为单位)*/
/C++中结构的大小*
printf(“%d\n”,(int)sizeof(x));
}
>P>以下,在C++和C++中有效,将在(c)和C++中<>代码> i <代码>中的不同值(最有可能)导致:
int i = sizeof('a');
有关差异的解释,请参见
另一份来自:
#包括
int sz=80;
内部主(空)
{
结构sz{char c;};
int val=sizeof(sz);//C中的sizeof(int),
C/SIEZOF(StReSZ)在C++中的应用
printf(“%d\n”,val);
返回0;
}
下面是一个利用C和C++中函数调用和对象声明之间的区别的例子,以及C90允许调用未声明函数:
#include <stdio.h>
struct f { int x; };
int main() {
f();
}
int f() {
return printf("hello");
}
#包括
结构f{int x;};
int main(){
f();
}
int f(){
返回printf(“你好”);
}
< C++ >这将不会打印任何东西,因为临时的<代码> f>代码>被创建和销毁,但是在C90中,它将打印<代码> hello >代码>,因为函数可以在没有声明的情况下调用。
<> >如果您对使用代码两次“代码> f>代码>感到困惑,C++和C++标准明确允许,如果您想要这个结构,则必须创建一个对象:“代码>结构SF f/CODE”,以消除歧义,或者如果您想要函数,请删除<代码>结构> /代码>
a.逗号运算符在C语言中执行左值到右值的转换,但不在C++中执行:
char arr[100];
int s = sizeof(0, arr); // The comma operator is used.
在C++中,这个表达式的值将是100,而在C中,这将是<代码> siZeof(char)
<强> B.<强> C++中枚举器的类型是枚举。在C语言中,枚举数的类型是int
enum E { a, b, c };
sizeof(a) == sizeof(int); // In C
sizeof(a) == sizeof(E); // In C++
这意味着sizeof(int)
可能不等于sizeof(E)
<> >强> C.<强> C++中,空PARAMS列表声明的函数不带参数。在C中,空参数列表表示函数参数的数量和类型未知
int f(); // int f(void) in C++
// int f(*unknown*) in C
C90对C++11(int
对double
):
#包括
int main()
{
自动j=1.5;
printf(“%d”,(int)sizeof(j));
返回0;
}
在Cauto中
表示局部变量。在C90中,可以省略变量或函数类型。它默认为int
。在C++ 11中,代码>自动< /代码>意味着完全不同的东西,它告诉编译器从变量初始化的类型来推断变量的类型。 <>对于C++ +c90,至少有一种方法获得不同的行为,而不是定义的实现。C90没有单行注释。稍加关心,我们就可以用它来创建一个表达式,在C90和C++中有完全不同的结果。
int a = 10 //* comment */ 2
+ 3;
在C++中,从<代码> //< /COD>到行的末尾的所有内容都是注释,因此,其结果如下:
int a = 10 + 3;
由于C90没有单行注释,因此只有/*注释*/
是注释。第一个/
和2
都是初始化的一部分,因此其结果是:
int a = 10 / 2 + 3;
这样,一个正确的C++编译器将给出13个,但严格正确的C90编译器8。当然,我只是在这里选择了任意的数字,你可以使用你认为合适的其他数字。
C中的内联函数默认为外部范围,C++中没有。
编译以下两个文件一起打印“GnIn”,以GNUC为例,但C++没有什么。
文件1
#include <stdio.h>
struct fun{};
int main()
{
fun(); // In C, this calls the inline function from file 2 where as in C++
// this would create a variable of struct fun
return 0;
}
#包括
结构乐趣{};
int main()
{
fun();//在C中,它从文件调用内联函数
int a = 10 //* comment */ 2
+ 3;
int a = 10 + 3;
int a = 10 / 2 + 3;
#include <stdio.h>
struct fun{};
int main()
{
fun(); // In C, this calls the inline function from file 2 where as in C++
// this would create a variable of struct fun
return 0;
}
#include <stdio.h>
inline void fun(void)
{
printf("I am inline\n");
}
#include <stdio.h>
int main() {
printf("%d\n", (int)sizeof !0);
}
#include <stdio.h>
int main()
{
#if true
printf("true!\n");
#else
printf("false!\n");
#endif
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int d = (int)(abs(0.6) + 0.5);
printf("%d", d);
return 0;
}
#include <cstdio>
void foo(int r)
{
printf("I am C++\n");
}
#include <stdio.h>
void foo(int r)
{
printf("I am C\n");
}
extern void foo(int);
int main(void)
{
foo(1);
return 0;
}
$ diff main.cpp main.c
$ gcc -o test main.cpp foo.cpp foo2.c
$ ./test
I am C++
$ gcc -o test main.c foo.cpp foo2.c
$ ./test
I am C
#include <stdio.h>
struct A {
double a[32];
};
int main() {
struct B {
struct A {
short a, b;
} a;
};
printf("%d\n", sizeof(struct A));
return 0;
}
int a = 5;
a++ = 2; /* error: lvalue required as left operand of assignment */
++a = 2; /* error: lvalue required as left operand of assignment */
int a = 5;
a++ = 2; // error: lvalue required as left operand of assignment
++a = 2; // No error: a gets assigned to 2!
int x = a;
int x = ++a;
int a;
a = 2;
++a = 2; // Valid in C++.
#include <stdio.h>
typedef struct {} Foo;
int main()
{
printf("%zd\n", sizeof(Foo));
return 0;
}
int main(void) {
const int dim = 5;
int array[dim];
}
int main(void) {
const int dim = 5;
int array[dim] = {0};
}