如何处理子函数中的 const 传播
How to deal with const propagation in subfunctions
我需要对现有函数进行修改,具有一些 const
输入参数:
int f(const owntype *r1, const owntype *r2)
为此,我想调用一个使用相同类型但没有 const
关键字的子函数:
void subfunction (owntype *src, owntype *dst)
我已经尝试过这个(以及其他一些变体),但它不起作用:
int f(const owntype *r1, const owntype *r2) {
...
subfunction((const owntyp*) r1);
...
}
如何在不更改两个函数的参数描述的情况下编译它?
(const owntype *)r1
是空操作,因为 r1
的类型已经是 const owntype *
.
被调用的函数(subfunction()
)需要一个owntype *
类型的参数。当将 r1
作为参数传递给 subfunction()
时,您可以将 r1
转换为 owntype *
,但是如果 subfunction()
试图修改该值,那么您就有大麻烦了。
想一想这两个函数的接口。
int f(const owntype *r1, const owntype *r2)
说:"Give me the addresses of two owntype
objects (r1
and r2
) and I promise I won't change the objects (const
)."
然后它在内部将 r1
和 r2
传递给 subfunction()
。 subfunction()
没有就其参数所指向的值做出任何承诺(那里没有 const
),并且可以随意更改它们。然后 returns 和 f()
在不知情的情况下食言。
这不是事情的运作方式,这就是为什么从 const
转换为非 const
是 undefined behaviour.
的原因
只要subfunction
不尝试写入指向的对象*r1
和*r2
就可以通过转换调用它:
subfunction(owntype*)r1, (owntype*)r2);
标准(§6.7.3)说:
If an attempt is made to modify an object defined with a
const-qualified type through use of an lvalue with non-const-qualified
type, the behavior is undefined.
所以,只要你不写入它,读取它就可以了。
最好的解决方案是修改 subfunction
以获取指向 const
的指针。
在实践中,有时这是不可能的(例如,需要修改由于组织惯例而不允许修改的代码)。在这些情况下你可以写:
subfunction( (owntype *)r1, (owntype *)r2 );
这是正确的,只要您确定 subfunction
不会修改指向的对象。如果它确实尝试修改它们,那么在尝试修改时将导致未定义的行为。
如果您不确定 subfunction
的作用,并且想进行防御性编程,那么另一种选择是复制对象:
owntype c1 = *r1, c2 = *r2;
subfunction( &c1, &c2 );
请注意,检查复制是否不会破坏 owntype
的 class 不变量。
其他一些 answers/comments 建议丢弃 const 可能是未定义的行为。然而事实并非如此。相关引用是C11 6.7.3/6:
If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined.
Link to question on that topic
您已声明 subfunction
不会更改输入。这是 purpose/design 还是将来的更改可能会导致修改输入?
在第一种情况下,将输入定义为 not const
显然是一个错误。
由于 subfunction
似乎在您的控制之下:修复界面 -> 完成!
在第二种情况下(接口的 const
ness 被正确选择)还有:不要删除常量!对该函数的未来更改可能会在意想不到的地方破坏您的代码。而是制作一个本地副本并将副本用作 subfunction
.
的参数
来自评论:
subfunction() does not modify the mentioned parameters, but it's widespread in the application, and at every place, a variable, not declared as const, is used for it. If I change the signature of subfunction(), I'll need to do modifications through the whole program, which I want to avoid.
请注意,向使用 const
参数定义的函数提供非常量参数是完全没问题的。因此,除非 subfunction
调用其他具有非常量参数的函数,否则如果将参数更改为 const
.
它将正常工作
请注意,如果您想在现有代码中引入 const
,最简单的做法是自下而上。从最基本的函数(那些不调用任何其他函数的函数)开始,然后逐步向上调用层次结构。这样你就可以一点一点地做。如果您从顶部开始(如 main
中),则代码将不会再次编译,直到您在所有地方都进行了更改。
我需要对现有函数进行修改,具有一些 const
输入参数:
int f(const owntype *r1, const owntype *r2)
为此,我想调用一个使用相同类型但没有 const
关键字的子函数:
void subfunction (owntype *src, owntype *dst)
我已经尝试过这个(以及其他一些变体),但它不起作用:
int f(const owntype *r1, const owntype *r2) {
...
subfunction((const owntyp*) r1);
...
}
如何在不更改两个函数的参数描述的情况下编译它?
(const owntype *)r1
是空操作,因为 r1
的类型已经是 const owntype *
.
被调用的函数(subfunction()
)需要一个owntype *
类型的参数。当将 r1
作为参数传递给 subfunction()
时,您可以将 r1
转换为 owntype *
,但是如果 subfunction()
试图修改该值,那么您就有大麻烦了。
想一想这两个函数的接口。
int f(const owntype *r1, const owntype *r2)
说:"Give me the addresses of two owntype
objects (r1
and r2
) and I promise I won't change the objects (const
)."
然后它在内部将 r1
和 r2
传递给 subfunction()
。 subfunction()
没有就其参数所指向的值做出任何承诺(那里没有 const
),并且可以随意更改它们。然后 returns 和 f()
在不知情的情况下食言。
这不是事情的运作方式,这就是为什么从 const
转换为非 const
是 undefined behaviour.
只要subfunction
不尝试写入指向的对象*r1
和*r2
就可以通过转换调用它:
subfunction(owntype*)r1, (owntype*)r2);
标准(§6.7.3)说:
If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined.
所以,只要你不写入它,读取它就可以了。
最好的解决方案是修改 subfunction
以获取指向 const
的指针。
在实践中,有时这是不可能的(例如,需要修改由于组织惯例而不允许修改的代码)。在这些情况下你可以写:
subfunction( (owntype *)r1, (owntype *)r2 );
这是正确的,只要您确定 subfunction
不会修改指向的对象。如果它确实尝试修改它们,那么在尝试修改时将导致未定义的行为。
如果您不确定 subfunction
的作用,并且想进行防御性编程,那么另一种选择是复制对象:
owntype c1 = *r1, c2 = *r2;
subfunction( &c1, &c2 );
请注意,检查复制是否不会破坏 owntype
的 class 不变量。
其他一些 answers/comments 建议丢弃 const 可能是未定义的行为。然而事实并非如此。相关引用是C11 6.7.3/6:
If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined.
Link to question on that topic
您已声明 subfunction
不会更改输入。这是 purpose/design 还是将来的更改可能会导致修改输入?
在第一种情况下,将输入定义为 not const
显然是一个错误。
由于 subfunction
似乎在您的控制之下:修复界面 -> 完成!
在第二种情况下(接口的 const
ness 被正确选择)还有:不要删除常量!对该函数的未来更改可能会在意想不到的地方破坏您的代码。而是制作一个本地副本并将副本用作 subfunction
.
来自评论:
subfunction() does not modify the mentioned parameters, but it's widespread in the application, and at every place, a variable, not declared as const, is used for it. If I change the signature of subfunction(), I'll need to do modifications through the whole program, which I want to avoid.
请注意,向使用 const
参数定义的函数提供非常量参数是完全没问题的。因此,除非 subfunction
调用其他具有非常量参数的函数,否则如果将参数更改为 const
.
请注意,如果您想在现有代码中引入 const
,最简单的做法是自下而上。从最基本的函数(那些不调用任何其他函数的函数)开始,然后逐步向上调用层次结构。这样你就可以一点一点地做。如果您从顶部开始(如 main
中),则代码将不会再次编译,直到您在所有地方都进行了更改。