值参数的Const正确性

jmu*_*llo 26 c++ const-correctness pass-by-value

我知道关于const正确性的问题很少,其中声明函数的声明及其定义不需要同意值参数.这是因为值参数的常量仅在函数内部很重要.这可以:

// header
int func(int i);

// cpp
int func(const int i) {
    return i;
}
Run Code Online (Sandbox Code Playgroud)

这样做真的是最好的做法吗?因为我从未见过有人这样做过.我已经在其他地方看过这个引用(不确定来源),这已被讨论过:

"事实上,对于编译器,无论是否在值参数前面包含此const,函数签名都是相同的."

"避免在函数声明中使用const值传递参数.如果不修改参数const,则仍然将参数const置于同一函数的定义中."

第二段说不要将const放在声明中.我假设这是因为值参数的常量作为接口定义的一部分是没有意义的.这是一个实现细节.

根据这个建议,是否也建议指针参数的指针值?(它对参考参数没有意义,因为您无法重新分配参考.)

// header
int func1(int* i);
int func2(int* i);

// cpp
int func1(int* i) {
    int x = 0;

    *i = 3; // compiles without error
    i = &x; // compiles without error

    return *i;
}
int func2(int* const i) {
    int x = 0;

    *i = 3; // compiles without error
    i = &x; // compile error

    return *i;
}
Run Code Online (Sandbox Code Playgroud)

简介:创建值参数有助于捕获一些逻辑错误.这是最佳做法吗?你是否将const留在头文件中?它对const指针值有用吗?为什么或者为什么不?

一些参考:

C++ const关键字 - 大量使用? 使用'const'作为函数参数

const值参数有用的示例:

bool are_ints_equal(const int i, const int j) {
    if (i = j) { // without the consts this would compile without error
        return true;
    } else {
        return false;
    }
    // return i = j; // I know it can be shortened
}
Run Code Online (Sandbox Code Playgroud)

Mic*_*urr 10

我已多次读过在函数const中创建值参数是一件坏事,因为它是不必要的.

但是,我觉得它有时对我有帮助,因为检查我的实现没有做我不想做的事情(如问题末尾的例子).

因此,虽然它可能不会给调用者增加价值,但它有时会为我作为一个实现者添加一点点价值,并且它不会从调用者那里带走任何东西.所以我觉得使用它没什么坏处.

例如,我可能正在实现一个C函数,它接受一个指向缓冲区的指针 - 指向开始的指针和指向结尾的指针.我要将数据放入缓冲区,但是要确保我不会超出结束范围.因此,在函数内部有代码,当我向其添加数据时,它会递增指针.使指针指向缓冲区的末尾一个const参数将确保我不编码一个错误,该错误意外地增加了结束边界指针,而不是我真正应该递增的指针.

所以fillArray函数的签名如下:

size_t fillArray( data_t* pStart, data_t* const pEnd);
Run Code Online (Sandbox Code Playgroud)

pEnd当我真的想要增加时,会阻止我意外地增加pStart.这不是一件大事,但我很确定在C中任何时间段编程的每个人都遇到过这样的错误.


luk*_*uke 9

我接受它:

这不是一个坏主意,但问题很小,你的能量可能会更好地花在其他事情上.

在你的问题中,你提供了一个很好的例子,说明它什么时候可能发现错误,但偶尔你也会这样做:

void foo(const int count ...)
{
   int temp = count;  // can't modify count, so we need a copy of it
   ++temp;

   /* ... */
}
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,优点和缺点都很小.

  • 通常当你修改这样的变量时,你就会改变语义.例如:void foo(const int index0based){const int index1based = index0based + 1;}您可以将其称为索引并对其进行更改,但对于5年内出现的差的维护程序员来说,这一点要清楚得多. (8认同)
  • +1表示这不是一个坏主意,并且注意到这个问题很小.但是在你复制里面的参数之前,我只是删除了const(除非你总是复制"count",作为不对参数进行操作的原则,而不仅仅是因为const阻止了你) (3认同)