【问题标题】:Why the value is changed for the Read-Only Compound Literal?为什么只读复合文字的值会更改?
【发布时间】:2020-12-29 14:17:41
【问题描述】:

我正在研究 C 中的只读复合文字。当我尝试在取消引用运算符的帮助下更改其值时,值发生了变化! 我现在很困惑为什么会这样。

此外,当我编译并运行程序时(不尝试更改其值),它会显示此错误:

Code_Testing.c:5:14: warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
    5 |     int *r = (const int[3]){6, 14, -98}; // Read Only compound Literal
      |

我不明白为什么它忽略了const 限定符。

我知道const 限定符会丢弃任何更改,但这里复合文字的值发生了变化!

你能解释一下我在哪里犯了错误吗?

我写的程序是这样的:

#include <stdio.h>

int main(void)
{
    int *r = (const int[3]){6, 14, -98}; // Read Only compound Literal
    *r += 99;
    printf("The changed value is = %d", *r);
    return 0;
}

输出是:

Code_Testing.c:5:14: warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
    5 |     int *r = (const int[3]){6, 14, -98}; // Read Only compound Literal
      |              ^
The changed value is = 105

【问题讨论】:

  • 我知道const 限定符会丢弃任何更改 当您通过赋值或显式转换将其丢弃时不会。 C 语言中的const 非常弱——它甚至在相当长的一段时间内都不是语言的一部分。
  • “只读复合文字”是什么意思?复合文字通常不是只读的,但如果您使用 const 定义它们,它们就是只读的。

标签: c constants compound-literals


【解决方案1】:

您将const int[] 数组分配给指向非const 值的指针。这意味着作为程序员的明确放弃了const 限定符。 (右侧的 const 实际上确实将文字声明为 const。)

编译器会就此发出警告。

要修复您必须使用的警告

const int *r = (const int[3]){6, 14, -98}; // Read Only compound Literal

然后你会在该行得到一个错误

*r += 99;

您要修改值的位置。

const 限定符不会“放弃任何更改”。如您所见,有一些方法可以修改该值。 (但这是未定义的行为。)
const 限定符告诉编译器不应修改该值,并且当您的代码修改它或检测到可能导致修改 const 类型的值的使用时,编译器将显示错误或警告。

【讨论】:

  • 谢谢,实际上我认为在右侧添加const 会自动使文字成为常量。感谢您清除我的疑问:-)
  • 你是什么意思字面应该是const 反正? C 允许修改复合文字。
【解决方案2】:

如果您尝试使用非 const 限定类型的左值修改 const 限定对象的值,则为 undefined behavior

引用C11,第 6.7.3 章

如果尝试通过使用具有非 const 限定类型的左值来修改使用 const 限定类型定义的对象,则行为未定义。 [...]

这里的赋值丢弃了初始化器中的 const 限定符,并将其分配给一个非 const 限定的左值,所以你的编译器试图警告你潜在的陷阱。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-30
    • 1970-01-01
    • 2023-03-29
    • 2014-03-26
    • 2022-06-13
    • 1970-01-01
    相关资源
    最近更新 更多