C99 const 按值传递
我一直在研究 GNU 科学图书馆源代码,并且不断看到以下类型的声明:
double cblas_ddot (const int N, const double * x, const int incx, const double * y, const int incy)
在 C99 中,声明按值传递的参数是否有任何(优化)好处(例如 <上例中的 code>N 或 incy
)const
?无论如何,都有一个由它们组成的副本,因为它们是按值传递的,不是吗?
谢谢! 科内尔
I have been studying the GNU Scientific Library source code and I keep seeing the following type of declarations:
double cblas_ddot (const int N, const double * x, const int incx, const double * y, const int incy)
In C99, is there any (optimizational) benefit of declaring an argument that is passed by value (eg. N
or incy
in the example above) const
? There is a copy made of them anyway, because they are passed by value, isn't it?
Thx!
Kornel
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
对于调用者来说可能没有任何好处,但是对于被调用者来说。声明函数参数
const
与声明其他局部变量const
具有相同的有益影响,只要您尝试修改此参数,就会给您自己(作为函数的程序员)带来错误。在不太智能的实现中,如果内联函数,这样的声明也可能对决策产生影响。但我想现在的编译器会直接从函数的定义中推断出什么来做出这样的决定。
这种实现规范在其接口中表达当然可以被视为对语言的限制。
There is probably no benefit for the caller, but for the callee. Declaring a function parameter
const
has the same beneficial impact as declaring other local variablesconst
by imposing an error on yourself (as the programmer of the function) whenever you attempt to modify this.In not-so-smart implementations such a declaration could probably also have an impact on the decision if a function is inlined. But I guess that nowadays compilers will take such a decision on what they deduce from the definition of the function directly.
It can certainly viewed as a restriction of the language that this specification of the implementation is expressed in its interface.
是的。选项“const”通常用于声明传递给该函数的任何内容都不会被更改。编译方面,没有区别。它仍然是按值传递。
Yes. The option "const" is usually used to state that whatever is passed to this function will not be altered. Compile-wise, there is no difference. It is still passed by value.
正如其他人所说,函数以这种方式声明,以便在函数的范围内,该变量将不可更改,并且在这样做时,编译器应该警告您。
至于为什么要这样做,请考虑传递指针允许您执行的操作 - 即,您可以取消引用已传递的指针并编辑它指向的数据的值。使用 const 是防止您意外编辑调用者认为未更改的值的好方法。
例如,考虑一下:
这会输出
7+11=17
。现在这是一个微不足道的、不严重的情况,但如果我们依赖任何重要的东西,可能会发生各种各样的事情......如果你坚持 const 反对 y 变量,你应该得到:
编辑,以进一步说明:
为非指针变量声明
const
类型的一个很好的理由是用于表示某物大小的变量,或任何表示某物大小的变量保存数组的最大值。考虑一下:现在,您对自己说,但我永远不会编辑
source_len
。好吧,假设在你的算法中你出于某种原因而这样做。如果您的更改增加了 source_len 的值,则您将面临访问超出已分配内存的风险。如果您尝试修改该值,则在那里设置const
将生成编译器错误。我应该用双下划线指出,const 只是向编译器说“我保证不编辑它”的一种方式。它不保证内存是只读的,但它是标记您的意图以便捕获错误的一种方式。如果不需要修改它,将其声明为const。
既然你问了,两个版本生成的程序集是相同的。
As others have stated, functions are declared this way so that, within the scope of the function, that variable will not be changeable and in doing so, your compiler should warn you.
As to why you might want to do this, consider what passing a pointer allows you to do - namely, you can dereference the pointer you have passed and edit the values of the data to which it points. Using const is a good way to prevent yourself accidentally editing the value of something the caller thinks is unchanged.
By example, consider this:
This spits out
7+11=17
. Now this is a trivial, non-serious case but all sorts of things might happen were we to be relying on anything important...If you stick const against the y variable, you should get:
Edit, for further clarification:
One good reason to declare a
const
type for a non-pointer variable is for a variable that represents the size of something, or any variable that holds the maximum value of an array. Consider:Now, you say to yourself, but I'd never edit
source_len
. Well, let's say in your algorithm you do for whatever reason. If your change increases the value of source_len, you run the risk of accessing memory beyond what you've allocated.. Settingconst
there will generate a compiler error if you try to modify that value.I should point out, in double underlines, that const is only a way of saying to the compiler "I promise not to edit this". It does not guarantee that the memory is read-only, but it's a way of marking your intention such that you trap errors. If you don't need to modify it, declare it const.
And since you asked, the assembly generated by the two versions is identical.