简体   繁体   English

为什么转换 Foo** → const Foo** 在 C++ 中是一个错误,而在 C 中只是一个警告?

[英]Why converting Foo** → const Foo** is an error in C++, but only a warning in C?

char const c = 'x';       /* 1 */
char *p1;                 /* 2 */
char const **p2 = &p1;    /* 3 */
*p2 = &c;                 /* 4 */
*p1 = 'X';                /* 5 */

Line 3 is disallowed in C and is invalid in C++.第 3行在C 中是不允许的,在 C++ 中无效 However, one gets an error in C++, but only a warning in C. The question is - why only a warning?然而,一个人在 C++ 中得到一个错误,但在 C 中只有一个警告。问题是 - 为什么只有一个警告?

Both C & C++ deal with statement 3 as that "Assigning const char** with char** discards the const qualifier" The difference is; C 和 C++ 都将语句 3 处理为“使用char**分配const char** char**会丢弃const限定符”,区别在于; C++ is more strict than C and doesn't allow const qualifier discarding. C++ 比 C 更严格,并且不允许丢弃const限定符。 This is really convenient in C++ and does lead to no issues contrary to C.这在 C++ 中非常方便,并且不会导致与 C 相反的问题。

Imagine the following code:想象一下以下代码:

    char const c = 'x';
    char *p1 = &c;
    *p1 = 'A';

    printf("c address: 0x%X, p1 is pointing to: 0x%X\n", &c, p1);
    printf("%c\n", c);
    printf("%c\n", *p1);

This is a compilable C code.这是一个可编译的 C 代码。 One would think that assigning a new value to *p1 should not be possible as it points to a const variable.有人会认为为*p1分配一个新值应该是不可能的,因为它指向一个const变量。 Also one would think that if it did happen and we could change the value of what p is pointing at this will also change the value of c But this is not the case!!还有人会认为,如果它确实发生了,我们可以改变 p 指向的值,这也会改变c的值,但事实并非如此!!

The above code surprisingly generates:上面的代码出人意料地生成:

c address: 0xEF3E146B, p1 is pointing to: 0xEF3E146B
x
A

So allowing this const qualifier to be discarded does lead to undefined behavior (which means it's up to the compiler to decide what to do).因此,允许丢弃这个 const 限定符确实会导致未定义的行为(这意味着由编译器决定要做什么)。 This is fixed in C++ to avoid such ambiguities.这在 C++ 中是固定的,以避免这种歧义。

C has much more relaxed pointer rules than C++. C 的指针规则比 C++ 宽松得多。 C++ enforces a lot more type safety than C. Some of this is up to compilers to decide only to warn in C. C++ 比 C 强制执行更多的类型安全。其中一些取决于编译器决定只在 C 中发出警告。

One example to look at is malloc, where char* str = malloc(50);要查看的一个示例是 malloc,其中char* str = malloc(50); is perfectly fine C but must be char* str = (char*) malloc(50);非常好 C 但必须是char* str = (char*) malloc(50); in C++.在 C++ 中。

The short answer is: because they are different languages and have different rules.简短的回答是:因为它们是不同的语言并且有不同的规则。 There is no C/C++ language.没有 C/C++ 语言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM