为啥仅在某些情况下才能将字符串文字隐式转换为 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++11auto
功能,我无法想象它是使用“旧编译器”编译的。这个答案也没有解释为什么编译器(旧的与否)会让你摆脱第一次使用,而不是第二次。
@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* ? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
为啥在一种情况下会收到带有字符串文字的不推荐使用的转换警告,而在另一种情况下却没有?