是否存在向局部变量添加 const 限定符可能会引入运行时错误的情况?

发布于 2025-01-11 21:24:49 字数 569 浏览 0 评论 0原文

这是我多次执行过的(诚然是脑死亡的)重构算法:

  1. 从一个可以干净编译并且(AFAICT)正常工作的 .cpp 文件开始。
  2. 通读该文件,只要有未使用 const 关键字声明的本地/堆栈变量,请将 const 关键字添加到其声明中。
  3. 再次编译 .cpp 文件
  4. 如果报告任何新的编译时错误,请检查相关代码行以确定原因 - 如果事实证明本地变量确实需要是非< code>const,从中删除const关键字;否则修复 const 添加关键字所揭示的任何潜在问题。
  5. 转到 (3) 直到 .cpp 文件再次干净地编译

暂时搁置“const 所有局部变量”是否是一个好主意,是否有任何问题这种做法是否有将运行时/逻辑错误引入到程序中而在编译时无法捕获的风险? AFAICT 这看起来“安全”,因为它不会引入回归,只会引入编译时错误,然后我可以立即修复这些错误;但 C++ 是一个非常辉煌的东西,所以也许存在一些我没有想到的风险。

Here's an (admittedly brain-dead) refactoring algorithm I've performed on several occasions:

  1. Start with a .cpp file that compiles cleanly and (AFAICT) works correctly.
  2. Read through the file, and wherever there is a local/stack-variable declared without the const keyword, prepend the const keyword to its declaration.
  3. Compile the .cpp file again
  4. If any fresh compile-time errors are reported, examine the relevant lines of code to determine why -- if it turns out the local-variable legitimately does need to be non-const, remove the const keyword from it; otherwise fix whatever underlying issue the const keyword's addition has revealed.
  5. Goto (3) until the .cpp file again compiles cleanly

Setting aside for the moment whether or not it's a good idea to "const all the local variables", is there any risk of this practice introducing a run-time/logic error into the program that wouldn't be caught at compile-time? AFAICT this seems "safe" in that it won't introduce regressions, only compile-time errors which I can then fix right away; but C++ is a many-splendored thing so perhaps there is some risk I haven't thought of.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

极致的悲 2025-01-18 21:24:49

如果您愿意接受一个人为的示例,您可能会进入未定义行为的世界。

void increment(int & num)
{
    ++num;
}

int main()
{
    int n = 99;
    increment(const_cast<int&>(n));
    cout << n;
}

上面的编译并输出 100。下面的编译并允许做任何它想做的事情(但碰巧为我输出 99)。 通过非常量访问路径修改 const 对象会导致未定义的行为。

void increment(int & num)
{
    ++num;
}

int main()
{
    const int n = 99;
    increment(const_cast<int&>(n));
    cout << n;
}

是的,这是人为的,因为为什么有人会对非 const 对象执行 const_cast ?另一方面,这是一个简单的例子。也许在更复杂的代码中这实际上可能会出现。 耸耸肩我不会说这是一个很大的风险,但它确实属于“任何风险”,如问题中所述。

If you're willing to accept a contrived example, you could enter the world of undefined behavior.

void increment(int & num)
{
    ++num;
}

int main()
{
    int n = 99;
    increment(const_cast<int&>(n));
    cout << n;
}

The above compiles and outputs 100. The below compiles and is allowed to do whatever it wants (but happened to output 99 for me). Modifying a const object through a non-const access path results in undefined behavior.

void increment(int & num)
{
    ++num;
}

int main()
{
    const int n = 99;
    increment(const_cast<int&>(n));
    cout << n;
}

Yes, this is contrived because why would someone do a const_cast on a non-const object? On the other hand, this is a simple example. Maybe in more complex code this might actually come up. Shrug I won't claim that this is a big risk, but it does fall under "any risk", as stated in the question.

疏忽 2025-01-18 21:24:49

将 const 添加到变量可能会导致调用不同的重载:

https://godbolt.org/z/aE3jzPjP3< /a>

#include <stdexcept>

void func(int &) {
}

void func(const int &) {
    throw std::runtime_error("");
}

int main() {
    int var = 0;
    func(var);
}

var 更改为 const 将导致程序调用不同的函数,从而引发异常。

它可以很容易地触发完全不同的行为:

#include <map>
#include <iostream>

class Map {
public:
    std::map<int, int> data;
    int func() {
       return data[5];
    }
    int func() const {
       const auto iter = data.find(5);
       return iter == data.end() ? -1 : iter->second;
    }
};

int main() {
    Map m; // try with const
    std::cout << m.func(1) << std::endl;
    std::cout << m.data.size() << std::endl;
}

Adding const to a variable can cause a different overload to be called:

https://godbolt.org/z/aE3jzPjP3

#include <stdexcept>

void func(int &) {
}

void func(const int &) {
    throw std::runtime_error("");
}

int main() {
    int var = 0;
    func(var);
}

Changing var to const will cause the program to call a different function and thereby throw an exception.

It can easily trigger completely different behaviour:

#include <map>
#include <iostream>

class Map {
public:
    std::map<int, int> data;
    int func() {
       return data[5];
    }
    int func() const {
       const auto iter = data.find(5);
       return iter == data.end() ? -1 : iter->second;
    }
};

int main() {
    Map m; // try with const
    std::cout << m.func(1) << std::endl;
    std::cout << m.data.size() << std::endl;
}
剩余の解释 2025-01-18 21:24:49

const 没有运行时影响,编译器不会在编译时告诉您并导致构建失败。

const has no runtime implications, that the compiler will not tell you at compile time and fail the build.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文