【问题标题】:Undefined behavior when adding a const with const_cast?使用 const_cast 添加 const 时的未定义行为?
【发布时间】:2012-02-08 05:16:50
【问题描述】:

这个问题是关于我在使用const_cast 制作char * const char * 时观察到的行为。我知道此转换是隐式完成的,并且 t 在隐式完成转换时为我工作。

有问题的代码是:

#include <cstdlib>
int main() {
    const char * org_str = NULL;
    org_str = const_cast<const char*>(getenv("ENV_VAR")); // PROBLEM !!
}

根据Linux man page getenv() 接受const char * 并返回char*。因此,根据我对 const 正确性的理解,我可以毫无问题地对 char* 进行 const 转换。

所以,我的问题是,为什么 const_cast 在这里给了我一个 UB(代码正在崩溃),但正如预期的那样,没有 const_cast(隐式转换)它的工作正常(所以问题必须与使用 @987654333 @) ?

请注意,我知道隐式转换是要走的路,通过这篇文章,我需要专门针对此处观察到的行为的答案。

编辑:

由于其他 So'ers 无法重现该错误,因此我假设这是一些奇怪的运行时/编译器问题。但是,如果标准中提到了此类问题,请告诉我。

暂时我接受迈克的回答。

【问题讨论】:

  • 你确定这完全有效吗?由于getenv 是一个函数,因此它不应该编译,因为您不能通过添加或删除const 将函数指针转换为const char*。同样,这个const_cast添加 const,而不是删除它,所以它应该是安全的。我们可以看看你的实际代码吗?
  • 您的代码不完整。 sscce.org
  • 我已经编辑了代码。谢谢指出
  • 该代码没有任何问题。您的编译器或程序的其他部分一定有问题。
  • 是的,即使我认为它必须在其他地方。但是自从我删除了 const_cast 后它工作得很好。

标签: c++ undefined-behavior const-correctness const-cast


【解决方案1】:

您正在转换函数指针,而不是函数返回的指针。先用 () 调用函数,然后转换结果。

编辑:我无法重现该问题。这是我使用的代码:

#include <cstdlib>
#include <iostream>

using namespace std;
int main() {
    const char * org_str = NULL;
    org_str = const_cast<const char*>(getenv("PATH"));
    cout << "Got: " << org_str << endl;
}

这是我得到的:

$ g++ foo.cc -o foo.app
$ ./foo.app
Got: /usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/usr/X11R6/bin
$

顺便说一句,NULL 的赋值是不必要的;推荐的做法是使用以下之一:

const char *org_str = const_cast<const char*>(getenv("PATH"));

const char *org_str(const_cast<const char*>(getenv("PATH")));

const char *org_str(getenv("PATH"));

【讨论】:

  • 如果 OP 尝试使用 const_cast 强制转换函数指针,它甚至不会编译。发布的代码不是 OP 实际运行的代码。
  • 我已经编辑了代码。请检查,我想要一个环境变量“ENV_VAR”。
【解决方案2】:

你不需要 const_cast&lt;&gt; 来制作 const 的东西,你只需要它来消除 const-ness。

我也不相信你的代码是正确的,因为getenv 是一个函数,看起来你正在使用它作为变量。也许这样的事情会起作用:

const char * org_str = getenv("name-of-env");

【讨论】:

  • 我知道我不需要 cons_cast,但是当我使用它时出了什么问题,这就是问题所在。另外,我已经编辑了代码。
  • 我在 Visual Studio 2010 中尝试了您的示例代码,但没有出错。我怀疑是出了什么问题。
  • @在调试模式下构建时它也适用于我。它的优化模式无法正常工作。
【解决方案3】:

据我了解,这不是您应该转换的 getenv 的返回值,而是您拥有的 const char。由于 org_str 是常量,因此不使用 const_cast 就无法分配给它,这意味着您需要执行以下操作:

#include <cstdlib>
int main() {
    const char * org_str = NULL;
    const_cast<char*>(org_str) = getenv("ENV_VAR"); // NO PROBLEM !!
}

编辑:至于在 getenv 上使用 const_cast,这是没有意义的,因为您没有分配给它,因此不会有任何违反 const 表达式的行为,因为

org_str = getenv("ENV_VAR") will give you.

【讨论】:

  • 这有点奇怪,我同意。但这就是在:en.cppreference.com/w/cpp/language/const_cast 中所做的事情,当然,另一个用途是强制转换一个 const 对象,以更改它的值。至少这是我见过的仅有的两个用例。
  • 我试过这个并得到:warning: target of assignment not really an lvalue; this will be a hard error in the future.
  • @martiet:我认为左值转换只能与引用一起使用。不过需要挖掘标准;)
猜你喜欢
  • 1970-01-01
  • 2011-11-13
  • 1970-01-01
  • 2011-08-23
  • 2011-05-16
  • 1970-01-01
  • 2016-10-09
  • 2022-01-16
相关资源
最近更新 更多