是否“const”?只是意味着只读还是更多?
const
的真正含义是什么?只读似乎概括了它对我的意义,但是,我不确定我是对的。
如果只读和 const 不同,有人能告诉我为什么吗?
引发这个问题的原因是这个答案,其中他指出const
“just”意味着只读C. 我认为这就是全部 const
的意思,无论它是 C 还是 C++。他是什么意思?
为了回答 C 与 C++ 中 const 的具体差异,我创建了一个新问题:“const”在 C 和 C++ 中有何不同? 根据 R.. 的建议。
What does const
really mean? Read-only seems to encapsulate its meaning for me, but, I'm not sure I'm right.
If read-only and const
are different, could someone tell me why?
What prompted this question was this answer where he states const
"just" means read-only in C. I thought that's all const
meant, regardless of whether it was C or C++. What does he mean?
For an answer to the specific differences in const
in C vs C++, I've created a new question: How does "const" differ in C and C++? as per R..'s suggestion.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
通过将变量声明为 const,您可以向编译器表明您无意修改该变量。但并不代表别人没有!它只是为了允许一些优化并通过编译错误来通知(注意,这主要是编译错误,而 const == ReadOnly 意味着运行时错误)。
const
并不意味着只读,因为你可以写const volatile
,这意味着它可以随时自行更改,但我无意修改它。编辑:这是一个经典示例:考虑我正在编写从内存映射端口读取当前时间的代码。考虑 RTC 映射到内存 DWORD 0x1234。
它是
const
,因为它是一个只读端口,它是易失性
,因为每次我读取它时,它都会改变。另请注意,许多架构实际上将声明为 const 的全局变量设为只读,因为需要 UB 来修改它们。在这些情况下,UB 将表现为运行时错误。在其他情况下,这将是一个真正的 UB :)
这是一个很好的阅读:http: //publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html
By declaring a variable as
const
you indicate compiler that you have no intentions of modifying that variable. But it does not mean others don't have! It's just to allow some optimization and to be notified by a compile error (note, that it's mostly compile error, whileconst == ReadOnly
would mean runtime errors).const
does not mean read only, because you can writeconst volatile
, that would mean it could change by itself anytime, but I have no intentions to modify it.EDIT: here is a classical example: consider I'm writing the code that reads current time from a memory-mapped port. Consider that RTC is mapped to memory DWORD 0x1234.
It's
const
because it's a read-only port, and it'svolatile
because each time I will read it it will change.Also note that many architectures effectively make global variables declared as
const
read-only because it's UB to modify them. In these cases UB will manifest itself as a runtime-error. In other cases it would be a real UB :)Here is a good reading: http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html
编译器不允许修改声明为 const 的内容。正如你所说。
它主要用于函数原型中,以通知用户函数在传递指针时不会触及 this 或 that。它也可以作为你自己的故障保护。
The compiler won't allow something declared as
const
to be modified. It is as you say.It's mostly used in function prototypes to inform the user that a function won't touch this or that when passed pointers. It also works as kind of failsafe for yourself.
很多人告诉您
const
意味着您无法修改它。这是明显错误的。const
可以轻易地被丢弃。请注意这段代码:您的编译器不会阻止您执行此操作。那么,const 的目的是什么呢?我更愿意称之为建议。当您查看函数期望的合约函数原型时,它会提醒您。如果你不小心破坏了它,你的编译器会对你大喊大叫。 (但如果你故意破坏它,就像上面的强制转换一样。)
在某些情况下,标准会故意破坏
const
。请注意strstr
的返回值,例如:根据定义,它将返回一些偏移量到您提供的const
缓冲区中...但返回的值不是const
。为什么?好吧,在非 const 缓冲区上使用 strstr 的返回值会有意义地中断。A lot of people are telling you that
const
means you can't modify it. That is patently false.const
can trivially be cast away. Note this snippet:Your compiler will not stop you from doing this. So, what then is the purpose of
const
? I'd call it more of a suggestion. It reminds you as you look at function prototypes of the contract that your functions expect. Your compiler will yell at you if you carelessly break it. (But not if you intentionally break it, as with the above cast.)In some cases the standard intentionally breaks
const
. Note the return values ofstrstr
for example: by definition it will return some offset into theconst
buffer you provide it... But the returned value is notconst
. Why? Well, this would break meaningfully using the return value ofstrstr
on a non-const
buffer.两个字节相同的字节(除了注释)最小案例示例...
首先在 C 中,gcc 会发出警告...
现在 C++ 中同样的事情...g++ 对此非常满意。
Two byte for byte identical (except for the comments) minimal case examples...
First in C, gcc will emit a warning...
Now the same thing in C++... g++ is quite happy with it.
指针指向内存,
char *
指向数据段中的内存,该内存是只读的。char *
和char []
之间的区别在于,虽然两者在数据段上的声明方式相同,但char []
被视为可读,因为如果使用它,它就会被压入堆栈。Pointers point to memory, and
char *
points to memory in the data segment which is read only. The difference betweenchar *
andchar []
is that while both are declared the same way on the data segment,char []
is treated as readable because it is pushed onto the stack if it is used.C++ 允许定义 const 成员函数。 const 成员函数是唯一可以在 const 对象上调用的函数。此外,const 成员函数不能修改类的任何数据成员(除非该数据成员标记为可变)。
C++ allows for the definition of const member functions. const member functions are the only functions that be called on const objects. Also, const member functions cannot modify any data members of a class (unless the data member marked mutable).
Const 意味着指针或引用不能用于写入或读-修改-写操作,除非放弃 const。它并不意味着 C++ 标准试图声称的意思(C++ 标准在这一点上是错误的)。
像这样定义的变量:
显然不是只读的,否则它无法初始化。相反,变量 x 的类型是“引用 const 到 int”(而不是引用 const int)或者 int 的左值 const。请注意,“const”与指针或引用相关联,它与存储无关,也与该存储中驻留的值的类型无关。
这是相当不幸的,因为 const 提供的契约非常弱,特别是不允许缓存指向或引用的内存位置,正是因为它并不意味着不可变存储。
底线是:const 是与符号引用或指针关联的访问修饰符,程序员使用它来允许符号提供者在符号客户端上建立义务,或者让符号客户端向符号提供者承诺,它不会通过该符号修改存储(例如,接受指向 int 的指针 const 的函数承诺不会修改指向 int 的指针)。
这与变量无关:
并且显然与存储关系不大(malloc 存储总是可写的)。
相反,您应该将 const 视为在程序各部分之间传达不变量、义务或要求的一种方式,由程序员出于程序员的目的而放置,并由类型系统传播。不幸的是,类型系统并不健全,并且无法正确传播常量:
恕我直言,编译器使存储不可变的唯一机会是针对实际常量,例如字符串文字(可能)或静态(全局)存储。实际上,自动存储、堆存储和临时存储不能设为只读。
Const means that a pointer or reference cannot be used for a write or read-modify-write operation without casting away const. It does NOT mean what the C++ standard tries to claim it means (the C++ standard is just wrong on this).
A variable defined like this:
is patently NOT read-only since otherwise it could not be initialised. Rather, the kind of variable x is "reference const to int" (and NOT reference to const int) or alternatively lvalue const of int. Note carefully the "const" is associated with a pointer or reference it has nothing to do with the storage, nor the type of the value residing in that storage.
This is rather unfortunate because the contract provided by const is extremely weak, and in particular fails to allow caching of a pointed at or referred to memory location, precisely because it does NOT mean immutable storage.
The bottom line is: const is an access modifier associated with a symbolic reference or pointer which is used by the programmer to allow the symbol provider to establish an obligation on the symbol client, or for the symbol client to promise the symbol provider it does not modify storage via this symbol (for example a function accepting a pointer const to int promises not to modify the pointed at int).
This has nothing to do with variables:
and clearly little to do with storage (malloc'ed store is always writable).
Instead you should think of const as a way of communicating invariants, obligations or requirements between parts of the program, put in place by the programmer for the programmers purposes, and propagated by the type system. Unfortunately the type system isn't sound and fails to properly propagate constness correctly:
IMHO the only opportunity a compiler has to make store immutable is for actual constants such as string literals (maybe) or static (global) storage. Automatic, heap, and temporary storage cannot be made read-only in practice.