到const还是不到const——当我的代码获胜时要声明什么';t修改用户代码';s字符串,但我所依赖的第三方代码忘记声明常量?
将以下代码视为在组织中开发的大型项目,到const还是不到const——当我的代码获胜时要声明什么';t修改用户代码';s字符串,但我所依赖的第三方代码忘记声明常量?,c,arguments,parameter-passing,constants,C,Arguments,Parameter Passing,Constants,将以下代码视为在组织中开发的大型项目,我们的_function()是在内部开发的,我们都可以控制它main()是由我们的用户编写的,他们将链接到我们的库并调用我们的函数()。但是第三方函数()是由另一家外部公司开发的,我们对此没有控制权;我们只能按原样使用它 #include <stdio.h> void third_party_function(char *s) { // s[1] = 'E'; // We're sure that this function doesn't
我们的_function()
是在内部开发的,我们都可以控制它main()
是由我们的用户编写的,他们将链接到我们的库并调用我们的函数()。但是第三方函数()
是由另一家外部公司开发的,我们对此没有控制权;我们只能按原样使用它
#include <stdio.h>
void third_party_function(char *s)
{
// s[1] = 'E'; // We're sure that this function doesn't have code like this.
printf("third_party_function: s: %s\n", s);
}
void our_function(const char *s)
{
/* Do something with s but treat it as read-only. */
/* our_function depends on third_party_function. we know that
* third_party_function is never supposed to modify the string passed to it
* but the third party developer of third_party_function forgot to declare
* its argument as 'const char *', hence the type cast below. */
third_party_function((char *) s);
}
int main()
{
char *s = "hello, world";
/* Do something with s, but treat it as read-only. */
/* our_function is developed in-house; we are sure that our_function should
* never modify the string passed to it. */
our_function("hello, world");
/* Do something more with s. Here we just print it to make sure
* our_function() has not modified it. */
printf("main: s: %s\n", s);
return 0;
}
#包括
无效第三方函数(char*s)
{
//s[1]=“E”;//我们确信这个函数没有这样的代码。
printf(“第三方函数:s:%s\n”,s);
}
作废我们的函数(const char*s)
{
/*使用s执行某些操作,但将其视为只读*/
/*我们的函数依赖于第三方函数。我们知道这一点
*第三方函数永远不应该修改传递给它的字符串
*但是第三方函数的第三方开发者忘记声明了
*它的参数为“const char*”,因此类型转换如下*/
第三方功能((字符*);
}
int main()
{
char*s=“你好,世界”;
/*使用s执行某些操作,但将其视为只读*/
/*我们的_功能是在内部开发的;我们确信我们的_功能应该
*永远不要修改传递给它的字符串*/
我们的_功能(“你好,世界”);
/*用s做更多的事情。这里我们只是打印它以确保
*我们的函数()没有修改它*/
printf(“主:s:%s\n”,s);
返回0;
}
我们100%确信我们的函数()
永远不会修改传递给它的字符串
我们还100%确信第三方函数()
永远不会修改传递给它的字符串
但是第三方开发人员忘记用const
限定符限定third\u party\u function()
的参数
因此,现在我面临的困境是,是否用const
限定our_function()
的参数,从而告诉用户我们不会修改字符串
我有两个相反的论点:
作废我们的函数(const char*s)
的参数:我们想告诉用户他们的字符串不会被修改。因此,它们可以自由地传递常量字符串使我们的函数无效(const char*s)
:如果未来的第三方代码导致第三方函数()
修改它得到的字符串(假设他们取消注释s[1]='E'
语句),那么用户在编译时将不知道他们的代码可能在运行时由于分段错误而崩溃。他们在编译时可能得到的任何有用的诊断都会被强制的(char*)
类型转换抑制,这是将参数声明为const char*
的直接结果李>
这两个论点(耶!双关!)中哪一个是技术上正确的论点
注意:为了保持这个问题的客观性并防止它成为基于意见的问题,我正在寻找技术论据(而不是意见),以得出一个选项比另一个更好的结论。如果从技术角度来看,没有一个选项是好的,那么这就是正确的答案。如果有更好的选择,请在回答中告诉我。为了安全起见,复制您接收的C字符串,并使用副本调用第三方函数,并让您自己的函数使用const限定符(如果是语义)。要安全起见,复制您收到的C字符串,并使用该副本调用第三方函数,并让您自己的函数使用常量限定符(如果是其语义)。
const
不是创建合同的唯一方法。如果库函数有一个不改变数据的契约,那么就可以随意传递它,适当地丢弃const
Jean-Baptiste Yunes的回答很好,但这并不是传递给一个“忘记”声明const
的方法,而是传递给任何不受信任的依赖项。当然,如果它确实声明了const
,它仍然可以在内部忽略它,并做它想做的任何事情。你应该保护你的客户数据吗?可以说,是的
一种可能的情况是:该方法首先将接收到的字符串小写。然后对其执行非变异操作。因此,它当然不能声明
const
,即使合同通常保证它不是const。如果您的方法只接受小写字符串,const
,那么您可以随意使用库方法,丢弃const
const
并不是创建契约的唯一方法。如果库函数有一个不改变数据的契约,那么就可以随意传递它,适当地丢弃const
Jean-Baptiste Yunes的回答很好,但这并不是传递给一个“忘记”声明const
的方法,而是传递给任何不受信任的依赖项。当然,如果它确实声明了const
,它仍然可以在内部忽略它,并做它想做的任何事情。你应该保护你的客户数据吗?可以说,是的
一种可能的情况是:该方法首先将接收到的字符串小写。然后对其执行非变异操作。因此,它当然不能声明
const
,即使合同通常保证它不是const。如果你的方法只接受,const
,小写字符串,你应该可以随意使用library方法,抛弃const
把懒惰的开发人员踢到真正受伤害的地方,要么得到正确的lib版本,要么拿回你的钱,使用不同的lib。(是的,我有一个梦想…@Olaf踢第三方开发者是我无法控制的事情。我只能控制我在函数中编写的内容