【问题标题】:Type of a C++ string literalC++ 字符串文字的类型
【发布时间】:2013-08-27 16:58:53
【问题描述】:

出于好奇,我想知道 C++ 字符串文字的真正底层类型是什么。

根据我的观察,我得到不同的结果。

类似如下的 typeid 测试:

std::cout << typeid("test").name() << std::endl;

给我看char const[5]

尝试将字符串文字分配给这样的不兼容类型(查看给定错误):

wchar_t* s = "hello";

我从 VS12 的 IntelliSense 获得 a value of type "const char *" cannot be used to initialize an entity of type "wchar_t *"

但我不明白它怎么可能是const char *,因为 VS12 接受了以下行:

char* s = "Hello";

我已经读过这在 C++11 之前的标准中是允许的,因为它是为了与 C 进行追溯兼容,尽管修改 s 会导致未定义的行为。我假设这只是 VS12 尚未实现所有 C++11 标准,并且这一行通常会导致错误。

阅读 C99 标准(from here, 6.4.5.5)建议它应该是一个数组:

多字节字符 然后使用序列来初始化静态存储持续时间和长度的数组 足以包含序列。

那么,C++ 字符串文字下面的类型是什么?

非常感谢您宝贵的时间。

【问题讨论】:

  • VS12 说着一些奇怪的方言,与 C++ 相似,但又不完全相同。

标签: c++ string visual-studio-2012 c++11 types


【解决方案1】:

字符串文字的类型确实是const char[SIZE],其中SIZE 是字符串的长度加上空终止字符。

您有时会看到 const char* 是因为通常的数组到指针衰减。

但我不明白它怎么可能是const char *,因为 VS12 接受了以下行: char* s = "Hello";

这是 C++03 中的正确行为(作为通常的 const 正确性规则的例外),但此后已被弃用。符合 C++11 的编译器不应接受该代码。

【讨论】:

  • “通常的数组到指针衰减”并非在所有情况下都会发生。在 C 中,除非数组表达式是一元 &amp;sizeof 的操作数,或者是用于初始化数组(子)对象的初始化程序中的字符串文字,否则它会发生。 C++ 有更多的例外。
  • 正确的术语是Array-to-pointer Conversion,它是最新C++ 标准第4 条中记录的Standard Conversion。粗略地说,标准转换可能会在某些上下文中由编译器隐式应用于表达式。
【解决方案2】:

字符串文字的类型是char const[N],其中N 是包括终止空字符在内的字符数。尽管此类型转换为char*,但C++ 标准包含一个子句,允许将字符串文字分配给char*。添加此子句是为了支持兼容性,尤其是对于当时没有 const 的 C 代码。

标准中类型的相关条款是2.14.5 [lex.string]第8段:

普通字符串文字和 UTF-8 字符串文字也称为窄字符串文字。窄字符串文字的类型为“n const char 数组”,其中 n 是字符串的大小,定义如下,并且具有静态存储持续时间 (3.7)。

【讨论】:

  • 请注意,此异常子句现已弃用,尝试将字符串文字分配给 char* 会产生编译时错误。
  • @syam - “已弃用”意味着它仍然是合法的,但将来可能会消失。在 C++03 中不推荐将字符串文字转换为 char*;它在 C++11 中变得无效。但是,语言定义不需要“编译时错误”。对于违反可诊断约束,唯一的要求是编译器发出诊断;完成后,就可以继续编译代码了。这是特定于实现的扩展的钩子。只有一种情况需要编译器拒绝编译代码:#error 指令。
【解决方案3】:

首先,C++ 字符串文字的类型是 n const char 的数组。其次,如果你想用字符串文字初始化 wchar_t,你必须编写代码:

wchar_t* s = L"hello"

【讨论】:

  • 这并不是有效的代码,只是为了查看给定错误的测试。不过,该标准确实使它听起来应该是一个数组。
  • 不,字符串文字不是const char*,而是const char[SIZE],如其他答案中所述。 -1
  • 然后解释为什么sizeof "hello, world" 会产生 13。
  • @Keith:初始化字符串常量时,您会免费获得一个结束 0。
  • @Jongware 我知道。我要求 Paul Evans 解释为什么它与 sizeof (const char*) 不同。 (是的,我也知道。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-14
  • 1970-01-01
  • 2021-08-10
  • 2017-03-31
  • 2013-10-26
  • 1970-01-01
  • 2010-11-08
相关资源
最近更新 更多