它是确定的函数原型和功能实现签名不一致使用常量? [英] Is it OK for function prototypes and function implementation signatures to use const inconsistently?

查看:148
本文介绍了它是确定的函数原型和功能实现签名不一致使用常量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我喜欢甚至宣称值参数常量在可能的情况,并通过这样搜索,我发现的这不是太罕见。像这样的:

I like to declare even value parameters as const where possible, and by searching SO, I found that that's not too uncommon. Like this:

int add(const int a, const int b)
{
    ...
}

但我想知道:常量对于是我的函数的实现细节,而不是它的一部分的界面。因此将其放入原型似无必要。

But I'm wondering: const for values is an implementation detail of my function, not part of it's interface. So putting it into the prototype seems unnecessary.

这原型为上述功能似乎就好了工作:

This prototype for the above function seems to work just fine:

int add(int a, int b);

不过,我听说过这问题,例如声明的主要功能的ARGC为const可能导致问题:

Yet I've heard about issues that e.g. declaring the main function's argc as const can lead to problems:

int main(const int argc, const char* const argv[])

这是否意味着 INT增加(INT A,INT B) INT增加(const int的一个,const int的B)不相同毕竟?

如果它在技术上确定,是一些我应该怎么办?我也可以离开了变量名的原型,但我没有,所以也许我不应该离开了常量要么?

And if it's technically OK, is that something I should do? I could also leave out variable names in the prototype, but I don't, so maybe I shouldn't leave out const either?

推荐答案

这是不正常的的函数类型的不同,但你需要知道什么是函数类型的一部分​​,什么ISN吨。在你的情况下,常量的参数并不显著,因此函数类型相同,虽然的声明的看起来像是来自不同的定义

It's not OK for the function type to differ, but you need to know what is part of the function type and what isn't. In your case, the const for the parameters is not significant, so the function type is the same, although the declaration looks like it differs from the definition.

在你的情况下,它

5 一个名称,可用于在一个范围内几个不同的功能;这是函数重载(第13条)。一个函数的所有声明应同时在返回类型和参数类型列表正好一致。类型的功能的是使用以下规则来确定。每个参数的类型(包括函数参数包)是从自己的DECL说明符-SEQ和声明符确定。后
  确定每个参数的类型,类型的任何参数阵列的T或功能返回T被调整为指针T或指针返回T的函数,分别。生产参数类型的列表后,任何顶级cv修饰符修改参数类型形成该函数类型时被删除。得到的变换参数类型的列表和省略号或函数参数包的presence与否是函数的参数类型列表。 [注:这种转变不
  影响参数类型。例如, INT(*)(const int的P,decltype(P)*) INT(*)(INT,const int的*)是相同的类型。 - 注完]

8.3.5 Functions [dcl.fct]

5 A single name can be used for several different functions in a single scope; this is function overloading (Clause 13). All declarations for a function shall agree exactly in both the return type and the parameter-type-list. The type of a function is determined using the following rules. The type of each parameter (including function parameter packs) is determined from its own decl-specifier-seq and declarator. After determining the type of each parameter, any parameter of type "array of T" or "function returning T" is adjusted to be "pointer to T" or "pointer to function returning T," respectively. After producing the list of parameter types, any top-level cv-qualifiers modifying a parameter type are deleted when forming the function type. The resulting list of transformed parameter types and the presence or absence of the ellipsis or a function parameter pack is the function’s parameter-type-list. [ Note: This transformation does not affect the types of the parameters. For example, int(*)(const int p, decltype(p)*) and int(*)(int, const int*) are identical types. — end note ]

,因为它似乎,它需要一些解释,所以在这里我们去:在我们的情况下,最重要的一句话是:生产参数类型的列表后,修改参数类型的任何顶级CV-限定符时删除形成功能类型。

As it seems, it need some explanation, so here we go: The important sentence in our case is: After producing the list of parameter types, any top-level cv-qualifiers modifying a parameter type are deleted when forming the function type.

这意味着所有的顶级的CV-预选赛都删除。要解释什么是顶级的手段,我会以非法的方式写类型,强调什么是常量指的是:

This means that all top-level cv-qualifier are remove. To explain what top-level means, I'll write types in an illegal way to emphasize what a const refers to:


  • const int的 = (常量(INT)) - >这是一个顶级常量

  • const int的* = ((常量(INT))*) - >不是顶级,它的在第二级

  • const int的*常量 = (((常量(INT))*)常量) - >第二常量是在顶级

  • const int的&安培; = ((常量(INT))及) - >不是顶级

  • const int = (const (int)) -> this is a top-level const
  • const int* = ((const (int))*) -> not top-level, it's at the second level
  • const int* const = (((const (int))*) const) -> the second const is at top-level
  • const int& = ((const (int))&) -> not top-level

我希望这将清除有关函数类型的一些误解了。

I hope this clears some misconceptions about function types up.

有关的其他问题。我建议保持声明和定义是相同的,因为它可能会混淆人(像这个问题证明;)

For your other questions: I'd advise to keep the declaration and the definition identical, as it might confuse people (like evidenced by this question ;).

有关的例子,你给:

int main( const int argc, const char* const argv[] )

,根据从标准以上报价,相当于

is, according to the above quote from the standard, equivalent to:

int main( int argc, const char* const* argv )

所以添加常量的argv 不会最终成为一个顶级常量被删除,因此它是一个病态的功能类型,其中预计:

so the added const for argv does not end up as a top-level const which is removed and it's therefore an ill-formed function type for main, which expects:

int main( int argc, char** argv )

您要离开了参数名称最后一个问题:我不会做它,因为对我来说,他们的的文件的部分功能。他们传达的意图和功能的语义(如果你选择它们明智地)。

You last question about leaving out the parameter names: I wouldn't do it because to me, they are part of the documentation of the function. They communicate the intent and the semantics of the function (if you choose them wisely).

这篇关于它是确定的函数原型和功能实现签名不一致使用常量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆