为啥仅在某些情况下才能将字符串文字隐式转换为 char* ? [复制]

Posted

技术标签:

【中文标题】为啥仅在某些情况下才能将字符串文字隐式转换为 char* ? [复制]【英文标题】:Why can a string literal be implicitly converted to char* only in certain case? [duplicate]为什么仅在某些情况下才能将字符串文字隐式转换为 char* ? [复制] 【发布时间】:2013-01-03 03:23:17 【问题描述】:
void f(char* p)


int main()

    f("Hello"); // OK

    auto p = "Hello";

    f(p); // error C2664: 'void f(char *)' : cannot convert parameter 1 
          // from 'const char *' to 'char *'
 

代码使用 VC++ Nov 2012 CTP 编译。

§2.14.15 字符串文字,第 7 节

窄字符串文字的类型为“n const char 数组”,其中 n 是 字符串的大小如下定义,并具有静态存储 持续时间。

为什么f("Hello") 可以?

【问题讨论】:

一个更具描述性的问题是“为什么我的编译器没有报告f("Hello") 的错误?” @DrewDormann - 但你的标题只对 tenOP 有帮助 - 对于其他用户来说,更通用的标题是有用的 - 标题 +1 @Mark 我认为标题很好。关于“OK”的问题具有误导性。 在 C 中,p 是 int,而不是 const char*。它被声明为自动范围,但没有类型(因此默认为int)。这个问题的C标签应该被删除。 【参考方案1】:

至少在理论上,这种行为在 C 和 C++ 之间有所不同。

在 C 语言中: 字符串文字衰减为非常量指针。但是,这并不是一个好主意。试图通过该指针修改字符串会导致未定义的行为。

在 C++ 中: 永远不行(AFAIK)。* 但是,一些编译器可能仍然会让你侥幸逃脱。例如,GCC 具有 -Wwrite-strings 标志,默认情况下启用(至少在 4.5.1 及更高版本中)。


* 至少在 C++11 中。 (我手头没有旧规格。)

【讨论】:

我编译成C++代码,但是没问题。 我同意,在 C 语言中它是允许的,因为很久以前 const 不是该语言的一部分,因此可以确保使用文字的代码仍然可以传递给非 const 函数工作。 只是一个细节:在 C++03 中,支持从文字到 char* 的转换,但我记得不推荐使用;无论如何,在 C++11 中它已被删除,无效代码 鉴于代码包含 C++11 auto 功能,我无法想象它是使用“旧编译器”编译的。这个答案也没有解释为什么编译器(旧的与否)会让你摆脱第一次使用,而不是第二次。 @sepp2k:微软的编译器从来都不擅长标准合规性。【参考方案2】:

两者的区别

f("Hello");

f(p);

是前者涉及文字。在 C++03 中,支持从字符串文字到 char*(注意:不是 const)的转换。 C++11 不再支持它,但很少有编译器跟上该规则的变化。

【讨论】:

+1 这最好地回答了这个问题。【参考方案3】:
f("Hello");

即使这在 C++ 中也不行。编译器应该给出诊断,否则需要更新。

在 C++ 中,"Hello" 可转换为 const char*,而不是 char*

"Hello"char* 的转换在 C++03 中是允许的,尽管它已弃用。而在C++11中,转换无效,代码格式不正确。

【讨论】:

我相信它仍然支持向后兼容性,但已弃用 我用最新的 VC++ Nov 2012 CTP 编译了它 好吧,祝你更新编译器好运。微软以不遵守标准而闻名(这也是他们没有 C99 编译器的原因)。 @AndyProwl:我认为它在 C++03 中已被弃用,在 C++11 中格式错误。 @Nawaz:好的,谢谢你的澄清【参考方案4】:

我认为是因为 auto 关键字。它是类型推导,所以编译器不再知道如何转换为 char*。

【讨论】:

这不是问题。字符串文字是 const char*,而不是 char*f("Hello") 应该受到类型错误的惩罚,但事实并非如此。

以上是关于为啥仅在某些情况下才能将字符串文字隐式转换为 char* ? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥 glreadpixels 仅在某些情况下有效?

为啥 MISRA-C 在某些情况下不允许隐式扩展类型?

为啥在一种情况下会收到带有字符串文字的不推荐使用的转换警告,而在另一种情况下却没有?

Java - 为啥 char 不应该被隐式转换为字节(和短)原语?

sql语句中怎样将字符类型转换成数字类型

Java 中的隐式转换是如何工作的?