为什么函数声明中允许 const?
Why is const allowed in function declarations?
在 C 和 C++ 中,参数可以在定义函数时声明const
:
// without const
void foo(int i)
{
// implementation of foo()
}
// with const
// const communicates the fact that the implementation of foo() does not modify parameter i
void foo(const int i)
{
// implementation of foo()
}
但是,从调用方的角度来看,两个版本是相同的(具有相同的签名(。将复制传递给foo()
的参数的值。foo()
可能会更改该副本,而不是调用方传递的值。
这一切都很好,但是在声明foo()
时也允许使用const
:
void foo(int i); // normal way to declare foo()
void foo(const int i); // unusual way to declare foo() - const here has no meaning
为什么C和C++标准在声明foo()
时允许const
,即使它在这样的声明中毫无意义?为什么要允许如此荒谬地使用const
?
const
是一个类型限定符:https://en.cppreference.com/w/cpp/language/cv
因此,它们可以作为语法本身的一部分添加到类型中。我想他们不想以不同的方式指定参数和变量。(它可能使实现更容易一些?
那么问题来了,正如你在问题中所说,当他们引用论点本身时,它们不参与签名(例如,当他们提到论点所指向的内存时,它们是签名的一部分(。
叮叮当当有一条规则来删除多余的const
: https://clang.llvm.org/extra/clang-tidy/checks/readability-avoid-const-params-in-decls.html
没有理由禁止在非定义声明中使用函数参数上的限定符,并且允许它允许源代码在定义和任何非定义声明中保留相同的声明。
在定义中,const
和其他限定符具有其正常效果,如下所示:
int foo(const int x)
{
x = 3; // Not permitted.
}
假设我们不希望失去这种行为,允许在定义中使用限定符,同时在非声明的声明中禁止它们,这将不必要地使标准复杂化。此外,这意味着复制定义以将其作为非定义声明粘贴到其他地方的人将不得不进行额外的编辑,并且任何旨在从源文件中收集外部定义以创建包含非定义声明的头文件的软件都必须执行额外的解析和操作来去除限定符(但只有顶级限定符,如int * const p
, 其中const
限定p
,而不是类型内部的那些,如const int *p
,其中const
限定类型p
指向,而不是p
(。
通常,C 和 C++ 语言不禁止"无用"的事情,例如添加常量零(这可能来自预处理器宏的组合,其中某些表达式碰巧在某些构建选项选择时计算为零(、隔离的空语句等。这些事情并不重要,除非它们有助于人类犯错误的倾向。例如,如果添加零总是由于错误而发生(因此它从未发生过如上所述的结果(,那么禁止它可能具有价值。但是,如果禁止某事没有价值,那么花费精力禁止它就是浪费。
首先,函数参数的 lis 中的常量并非毫无意义。请考虑以下代码:
void foo(int i)
{
i++;
std::cout << i << "n";
}
如果添加 const 是不可能的。如果按值传递参数,则按值传递的参数是函数的局部变量。声明它 const 告诉编译器变量 i 在其生命周期内无法更改其值。
还是没多大用处?在 C 中,也许吧。在C++这也意味着您不能调用按值传递的类型类的非 const 方法。假设参数可以是类类型的对象,并且是存储在函数外部的某个对象的接口。然后,声明函数必须使该对象保持"不可变"确实有意义。
Const 不会参与这种特殊情况以形成函数签名,因此在同一作用域中或在名称查找期间遇到这两个变体会导致程序格式不正确。在其他情况下,它可以定义参数值类别的差异。
- 在 const 函数中通过引用和指针返回之间的区别
- 使用 std::string () const 函数启动线程或未来
- 如果我在 const 函数上使用指针,我可以返回什么?
- 为什么 const 函数返回左值而不是右值?
- 当我调用 main 中使用 const 对象的 const 函数时,不断出现错误
- 在 const 对象上调用非 const 函数
- 析构函数是否可以在 const 对象上调用非 const 函数
- C/C++ 如何在一次函数调用中交出 const 函数指针或简单指针
- 为什么我可以在C 11中使用const函数修改类
- 防止const函数被调用非const对象
- 如果C 中的支架重载运算符被声明为const函数
- C++:防止在 const 函数中更改指针的值
- 从const函数返回非const属性参考
- 调用指针参数从const函数指向的对象的操作员
- 在const函数中调用非CONST成员的非const函数
- 无法将 const 数据类型传递到非 const 函数中
- 这是检查 const 函数(如果是否创建某些内容)的更好方法
- 在 const 函数中从地图中未经选中读取
- 编译器不会为 "const" 和"not-const"函数给出不明确的错误吗
- 通过const函数中的参数索引返回std :: map的值