【问题标题】:Does implementation-definedness of char affect std::string?char 的实现定义会影响 std::string 吗?
【发布时间】:2016-09-09 21:12:12
【问题描述】:

我认为所有类型都已签名,除非另有说明(如 int)。我惊讶地发现 char 实际上是实现定义的:

... char 对象是否可以容纳由实现定义 负值。 ...在任何特定的实现中,一个普通的char 对象可以采用与 signed char 相同的值或 unsigned char;哪一个是实现定义的。

然而std::string 真的只是std::basic_string<char, ...>

这个程序的语义可以从实现中改变吗?

#include <string>

int main()
{
    char c = -1;
    std::string s{1, c};
}

【问题讨论】:

  • 是的,它确实会影响std::sring 的语义。
  • 您能否更具体地说明语义变化的含义?
  • 你能具体点吗? @SergeyA
  • 即满足所有前提条件,无论char是有符号还是无符号,所有效果都完全相同。 @juanchopanza
  • @user6331143 程序没有做任何事情,所以是的,你可以说语义没有改变。

标签: c++


【解决方案1】:

是和不是。

由于std::string 包含char 类型的对象,char 类型的签名会影响其行为。

您问题中的程序:

#include <string>

int main()
{
    char c = -1;
    std::string s{1, c};
}

没有可见的行为(除非终止而不产生任何输出是“行为”),所以它的行为不依赖于普通char的签名。编译器可以合理地优化main 的整个主体。 (诚​​然,我在这里吹毛求疵,评论的是您选择的代码示例,而不是您要问的问题。)

但是这个程序:

#include <iostream>
#include <string>

int main() {
    std::string s = "xx";
    s[0] = -1;
    s[1] = +1;
    std::cout << "Plain char is " << (s[0] < s[1] ? "signed" : "unsigned") << "\n";
}

将正确打印Plain char is signedPlain char is unsigned

请注意,使用该类型的operator&lt; 比较两个std::string 对象的类似程序区分普通char 是有符号还是无符号,因为&lt; 将字符视为它们没有签名,类似于 C 的 memcmp 的工作方式。

但这在 99% 的情况下都无关紧要。您几乎可以肯定必须不遗余力地编写行为取决于char 的签名的代码。您应该记住它是由实现定义的,但如果签名很重要,您应该明确使用signed char 或(更有可能)unsigned charchar 是数字类型,但您应该使用它来保存字符数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多