是否适合在函数参数中将字符串文字转换为char *?

时间:2012-10-31 01:05:30

标签: c++ function pointers char

我有一个接收char *参数的函数:

Foo::Foo (char * arg0) {
    ....
}

在原始示例中,char[]用于传递此值...

char bar[] = "Bar";
Instance.foo (bar);

......工作正常。

但是,我发现我可以传递一个字符串文字,强制转换为char *,而不会给编译器发出任何警告。

Instance.Foo ((char *) "Bar");

然而,从我的阅读中,似乎应该避免 - 指向的内存值可能会改变。

上述陈述是否属实(“应该避免这种情况”)或在这种情况下是否合适?


编辑 - 进一步研究this article,很好地解决了我的问题......

2 个答案:

答案 0 :(得分:8)

是的,避免这样做。现在,如果您的函数使用const char *,则使用字符串文字调用它没有任何问题。

C ++编译器仅支持字符串文字到char *,仅出于向后兼容性原因,写入字符串文字会导致未定义的行为。

当你执行char bar[] = "Bar";时,你正在做一些根本不同的事情(即初始化一个包含你可以自由修改的值{'B', 'a', 'r', '\0'}的4个字符的数组),而不是char bar* = "Bar";(你在哪里创建一个非const指向你不能修改的4字节字符串。

在我看来,您永远不应该将字符串文字直接转换为char*,而是将其放入const char*然后(如果您正在与遗留API进行通信)明确const_cast<char*> const离开时,评论说您正在与遗留API进行对话,该API保证不会更改char。这样做的好处是,您可以在升级API时搜索程序中的const_cast,或者您想要找到涉及写入char*的分段错误的来源。

甚至可以使用const char*版本中的const_cast封装旧版API。

绝对最糟糕的情况是会有一堆char*徘徊,其中一些是可写的,另一些来自字符串文字。

答案 1 :(得分:1)

应该几乎不惜一切代价避免这种情况,只有当你必须与破旧的遗传API接口时才会这样做,并且只有你看过他们的源代码并确保他们没有写入字符串。

保持安全,并在传递之前用strcpy复制字符串。

究竟什么是邪恶的?写入字符串文字是未定义的行为。