如何处理子函数中的const传播

时间:2016-09-22 09:43:03

标签: c const

我需要对现有函数进行修改,输入参数为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);
  ...
}

如何在不需要更改两个函数的parmeter描述的情况下编译它?

5 个答案:

答案 0 :(得分:5)

最佳解决方案是修改subfunction以指向const

在实践中,有时这是不可能的(例如,需要修改由于组织实践而不允许修改的代码)。在这些情况下,您可以写:

subfunction( (owntype *)r1, (owntype *)r2 );

只要您确定subfunction不修改指向的对象,这是正确的。如果确实尝试修改它们,则会在尝试修改时引起未定义的行为。

如果你不确定subfunction做了什么,并且你想要防御性地编程,那么另一个选择是获取对象的副本:

owntype c1 = *r1, c2 = *r2;
subfunction( &c1, &c2 );

注意,检查制作副本不会破坏owntype的类不变量。

其他一些答案/评论表明,抛弃const可能是未定义的行为。但事实并非如此。相关报价为C11 6.7.3 / 6:

  

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

Link to question on that topic

答案 1 :(得分:3)

只要Map<String,Integer> dataMap=new LinkedHashMap<String,Integer>(); //Your data map Map<Integer,Integer> countMap=new LinkedHashMap<Integer,Integer>(); //map to count data map entries //initializing with default value dataMap.put("a", 1); dataMap.put("b", 2); dataMap.put("c", 1); dataMap.put("d", 2); dataMap.put("e", 1); dataMap.put("f", 3); dataMap.put("g", 1); //main logic dataMap.forEach( (k,v) -> { if(countMap.get(v)==null) countMap.put(v, 0); Integer count=countMap.get(v); countMap.put(v,count+1); } ); //printing the count countMap.forEach( (k,v) -> { System.out.println(k+" "+v); } ); 没有尝试写入指向对象subfunction*r1,就可以通过强制转换来调用它:

*r2

标准(§6.7.3)说:

  

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

所以,只要你不写信,就可以从中读取它。

答案 2 :(得分:2)

您已声明subfunction不会更改输入。这是出于目的/设计还是未来的变化可能会导致修改输入?

在第一种情况下,将输入定义为const显然是一个错误。 由于subfunction似乎在您的控制之下:修复界面 - &gt;完成了!

在第二种情况下(接口的const ness被正确选择)也:不要删除const!对该函数的未来更改可能会在意外的位置上破坏您的代码。而是制作本地副本并将副本用作subfunction的参数。

答案 3 :(得分:1)

来自评论:

  

subfunction()不修改上述参数,但它在应用程序中很普遍,并且在每个地方都使用了一个未声明为const的变量。如果我更改了子函数()的签名,我需要对整个程序进行修改,我想避免这种修改。

请注意,为使用const参数定义的函数提供非const参数是完全正确的。因此,除非subfunction调用具有非const参数的其他函数,否则如果将参数更改为const,它将正常工作。

请注意,如果您想在现有代码中引入const,最简单的方法是自下而上。从最基本的功能(那些不会调用任何其他功能的功能)开始,然后按照调用层次结构的方式工作。这样你可以一点一点地做到这一点。如果你从顶部开始(比如在main中),代码将不会再次编译,直到你在任何地方都改变它为止。

答案 4 :(得分:-1)

(const owntype *)r1是免费操作,因为r1的类型已经是const owntype *

被调用函数(subfunction())需要类型为owntype *的参数。您可以将r1转换为owntype *作为参数传递给subfunction(),但如果subfunction()尝试修改该值,那么您将遇到大麻烦。

稍微考虑两个函数的接口。

int f(const owntype *r1, const owntype *r2)

说:&#34;给我两个owntype对象(r1r2)的地址,我保证我不会改变对象( const)&#34;

然后它在内部将r1r2传递给subfunction()subfunction()没有对其参数指向的值做出任何承诺(那里没有const),并且可以随意更改它们。然后它返回并且f()在不知情的情况下违背其承诺。

这不是事情的运作方式,这就是为什么从const转为非const undefined behaviour的原因。