在 C 和 C++ 中都有效的代码在用每种语言编译时是否会产生不同的行为?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12887700/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can code that is valid in both C and C++ produce different behavior when compiled in each language?
提问by user541686
C and C++ have many differences, and not all valid C code is valid C++ code.
(By "valid" I mean standard code with defined behavior, i.e. not implementation-specific/undefined/etc.)
C 和 C++ 有很多不同之处,并非所有有效的 C 代码都是有效的 C++ 代码。
(“有效”是指具有定义行为的标准代码,即不是特定于实现的/未定义的/等。)
Is there any scenario in which a piece of code valid in both C and C++ would produce differentbehavior when compiled with a standard compiler in each language?
当使用每种语言的标准编译器编译时,在 C 和 C++ 中都有效的一段代码是否会产生不同的行为?
To make it a reasonable/useful comparison (I'm trying to learn something practically useful, not to try to find obvious loopholes in the question), let's assume:
为了使它成为一个合理/有用的比较(我试图学习一些实际有用的东西,而不是试图在问题中找到明显的漏洞),让我们假设:
- Nothing preprocessor-related (which means no hacks with
#ifdef __cplusplus
, pragmas, etc.) - Anything implementation-defined is the same in both languages (e.g. numeric limits, etc.)
- We're comparing reasonably recent versions of each standard (e.g. say, C++98 and C90 or later)
If the versions matter, then please mention which versions of each produce different behavior.
- 没有与预处理器相关的内容(这意味着没有 hack
#ifdef __cplusplus
、pragma 等) - 任何实现定义在两种语言中都是相同的(例如数字限制等)
- 我们正在比较每个标准的最新版本(例如,C++98 和 C90 或更高版本)
如果版本很重要,那么请说明每个标准的哪些版本会产生不同的行为。
采纳答案by Alexey Frunze
The following, valid in C and C++, is going to (most likely) result in different values in i
in C and C++:
以下在 C 和 C++ 中有效,将(最有可能)i
在 C 和 C++ 中产生不同的值:
int i = sizeof('a');
See Size of character ('a') in C/C++for an explanation of the difference.
有关差异的说明,请参阅C/C++ 中的字符大小 ('a')。
Another one from this article:
这篇文章中的另一个:
#include <stdio.h>
int sz = 80;
int main(void)
{
struct sz { char c; };
int val = sizeof(sz); // sizeof(int) in C,
// sizeof(struct sz) in C++
printf("%d\n", val);
return 0;
}
回答by Seth Carnegie
Here is an example that takes advantage of the difference between function calls and object declarations in C and C++, as well as the fact that C90 allows the calling of undeclared functions:
下面是一个示例,它利用了 C 和 C++ 中函数调用和对象声明之间的差异,以及 C90 允许调用未声明函数的事实:
#include <stdio.h>
struct f { int x; };
int main() {
f();
}
int f() {
return printf("hello");
}
In C++ this will print nothing because a temporary f
is created and destroyed, but in C90 it will print hello
because functions can be called without having been declared.
在 C++ 中,这不会打印任何内容,因为f
创建和销毁了临时文件,但在 C90 中,它会打印,hello
因为可以在未声明的情况下调用函数。
In case you were wondering about the name f
being used twice, the C and C++ standards explicitly allows this, and to make an object you have to say struct f
to disambiguate if you want the structure, or leave off struct
if you want the function.
如果您想知道名称f
被使用了两次,C 和 C++ 标准明确允许这样做,并且要创建一个对象,您必须说struct f
如果需要结构就消除歧义,或者struct
如果需要函数就放弃。
回答by Jerry Coffin
For C++ vs. C90, there's at least one way to get different behavior that's not implementation defined. C90 doesn't have single-line comments. With a little care, we can use that to create an expression with entirely different results in C90 and in C++.
对于 C++ 与 C90,至少有一种方法可以获得未定义实现的不同行为。C90 没有单行注释。稍加注意,我们可以使用它来创建在 C90 和 C++ 中具有完全不同结果的表达式。
int a = 10 //* comment */ 2
+ 3;
In C++, everything from the //
to the end of the line is a comment, so this works out as:
在 C++ 中,从//
行尾到行尾的所有内容都是注释,因此其结果如下:
int a = 10 + 3;
Since C90 doesn't have single-line comments, only the /* comment */
is a comment. The first /
and the 2
are both parts of the initialization, so it comes out to:
由于 C90 没有单行注释,因此只有/* comment */
is 注释。first/
和 the2
都是初始化的一部分,所以结果是:
int a = 10 / 2 + 3;
So, a correct C++ compiler will give 13, but a strictly correct C90 compiler 8. Of course, I just picked arbitrary numbers here -- you can use other numbers as you see fit.
因此,正确的 C++ 编译器将给出 13,而严格正确的 C90 编译器将给出 8。当然,我只是在此处选择了任意数字——您可以使用您认为合适的其他数字。
回答by detunized
C90 vs. C++11 (int
vs. double
):
C90 与 C++11(int
对比double
):
#include <stdio.h>
int main()
{
auto j = 1.5;
printf("%d", (int)sizeof(j));
return 0;
}
In C auto
means local variable. In C90 it's ok to omit variable or function type. It defaults to int
. In C++11 auto
means something completely different, it tells the compiler to infer the type of the variable from the value used to initialize it.
在 C 中auto
表示局部变量。在 C90 中可以省略变量或函数类型。它默认为int
. 在 C++11 中auto
意味着完全不同的东西,它告诉编译器从用于初始化变量的值推断变量的类型。
回答by godlygeek
Another example that I haven't seen mentioned yet, this one highlighting a preprocessor difference:
另一个我还没有看到提到的例子,这个突出了预处理器的区别:
#include <stdio.h>
int main()
{
#if true
printf("true!\n");
#else
printf("false!\n");
#endif
return 0;
}
This prints "false" in C and "true" in C++ - In C, any undefined macro evaluates to 0. In C++, there's 1 exception: "true" evaluates to 1.
这会在 C 中打印“false”,在 C++ 中打印“true” - 在 C 中,任何未定义的宏的计算结果为 0。在 C++ 中,有 1 个例外:“true”的计算结果为 1。
回答by Kirill Kobelev
Per C++11 standard:
根据 C++11 标准:
a.The comma operator performs lvalue-to-rvalue conversion in C but not C++:
一种。逗号运算符在 C 但不是 C++ 中执行左值到右值的转换:
char arr[100];
int s = sizeof(0, arr); // The comma operator is used.
In C++ the value of this expression will be 100 and in C this will be sizeof(char*)
.
在 C++ 中,这个表达式的值将是 100,在 C 中这将是sizeof(char*)
.
b.In C++ the type of enumerator is its enum. In C the type of enumerator is int.
湾 在 C++ 中,枚举器的类型是它的枚举。在 C 中,枚举器的类型是 int。
enum E { a, b, c };
sizeof(a) == sizeof(int); // In C
sizeof(a) == sizeof(E); // In C++
This means that sizeof(int)
may not be equal to sizeof(E)
.
这意味着sizeof(int)
可能不等于sizeof(E)
。
c.In C++ a function declared with empty params list takes no arguments. In C empty params list mean that the number and type of function params is unknown.
C。在 C++ 中,用空参数列表声明的函数不带参数。在 C 中,空参数列表意味着函数参数的数量和类型是未知的。
int f(); // int f(void) in C++
// int f(*unknown*) in C
回答by Pavel Chikulaev
This program prints 1
in C++ and 0
in C:
这个程序1
用 C++ 和0
C打印:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int d = (int)(abs(0.6) + 0.5);
printf("%d", d);
return 0;
}
This happens because there is double abs(double)
overload in C++, so abs(0.6)
returns 0.6
while in C it returns 0
because of implicit double-to-int conversion before invoking int abs(int)
. In C, you have to use fabs
to work with double
.
这是因为有double abs(double)
在C ++中的过载,所以abs(0.6)
返回0.6
而在C中,它返回0
因为调用之前的隐式双到-INT转换int abs(int)
。在C语言中,你必须使用fabs
与工作double
。
回答by Adam Rosenfield
#include <stdio.h>
int main(void)
{
printf("%d\n", (int)sizeof('a'));
return 0;
}
In C, this prints whatever the value of sizeof(int)
is on the current system, which is typically 4
in most systems commonly in use today.
在 C 中,这会打印sizeof(int)
当前系统上的任何值,这通常4
在当今常用的大多数系统中。
In C++, this must print 1.
在 C++ 中,这必须打印 1。
回答by Alex B
Another sizeof
trap: boolean expressions.
另一个sizeof
陷阱:布尔表达式。
#include <stdio.h>
int main() {
printf("%d\n", (int)sizeof !0);
}
It equals to sizeof(int)
in C, because the expression is of type int
, but is typically 1 in C++ (though it's not required to be). In practice they are almost always different.
它sizeof(int)
在 C 中等于,因为表达式的类型为int
,但在 C++ 中通常为 1(尽管它不是必需的)。在实践中,它们几乎总是不同的。
回答by derobert
The C++ Programming Language (3rd Edition)gives three examples:
C++编程语言(第3版)给出了三个例子:
sizeof('a'), as @Adam Rosenfield mentioned;
//
comments being used to create hidden code:int f(int a, int b) { return a //* blah */ b ; }
Structures etc. hiding stuff in out scopes, as in your example.
sizeof('a'),正如@Adam Rosenfield 提到的;
//
用于创建隐藏代码的注释:int f(int a, int b) { return a //* blah */ b ; }
结构等将东西隐藏在范围之外,如您的示例所示。