当前位置: 首页 > 面试题库 >

在OS X上,简单的C ++程序给出了错误的结果(这是命令行选项'c ++ 03'与'c ++ 11'的结果)

赏彭薄
2023-03-14
问题内容

这个简单的程序(在Linux上编译时)将根据其是否编译正确地给出两个不同的答案-std=c++0x

问题:我无法在OS X(Mountain Lion,10.8 SDK)上重现相同的内容。我想念什么?

#include <iostream>
#include <sstream>

class Thing : public std::ostringstream
{
public:
    Thing() : std::ostringstream() {}
    virtual ~Thing() { std::cerr << str(); }
};

int main(int argc, const char * argv[]) {
    Thing() << "Hello" << std::endl;
    return 0;
}

要了解我的意思,请执行以下操作(首先在Linux上,仅查看其工作方式):

> g++ main.cpp
> ./a.out
0x401471
> g++ -std=c++0x main.cpp
> ./a.out
Hello

第一个将打印一个十六进制地址,第二个将打印“ Hello”。这是正确的行为,这是因为运算符<<解析为两种不同的情况(C ++
03中没有右值引用,因此可以使用)。

现在,在OS X上尝试相同的操作:

> xcrun c++ main.cpp
> ./a.out
0x10840dd88

(这将正确产生十六进制输出。)

> xcrun c++ -std=c++0x main.cpp
> ./a.out
0x10840dd88

(糟糕……仍然是十六进制输出……我们处于C ++ 11x模式,但是也许未使用正确的标头?)

注意:编译器的版本在这里:

> xcrun c++ --version
Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin12.2.0
Thread model: posix

注意:这本身不是C 问题,而是OS X构建问题。对于那些感兴趣的人,下面在答案之一中突出说明了它与C 03和C ++ 11产生不同结果的原因。


问题答案:

首先,行为上的预期差异是因为operator<<(std::ostream&, const char*)重载(实际上是函数模板的专门化,但暂时不要紧)具有类型参数,std::ostream&并且左值引用只能绑定到左值,并且在您的示例中,流是右值,因此无法使用重载。在C
03中,这意味着唯一可行的重载是 std::ostream::operator<<(const void*)成员函数,因为 可以
在rvalue对象上调用成员函数,因此该字符串 void*以十六进制形式写为地址。在C

11中,有一个新的operator<<(std::ostream&&, const T&)函数模板,该模板允许写入右值流并转发给operator<<(std::ostream&, const char*)重载,因此输出字符串而不是十六进制地址。

在GNU / Linux上,您大概使用的是最新版本的GCC版本,该版本在编译器(g )和标准库(libstdc )中都对C ++
11有很好的支持,因此它具有operator<<(std::ostream&&, const T&)重载功能,并且一切正常。

在OS X上,您可能将Clang与GCC的标准库libstdc 一起使用。Xcode默认附带一个古老版本的GCC(4.2),而GCC
4.2中的标准库不支持C
11,因此不存在operator<<右值流的重载。using -std=c++0x告诉Clang支持C
11语言功能(例如右值引用),但是并不能神奇地使GCC 4.2的库增长C
11代码,而当GCC
4.2出现时,这在标准委员会看来并不是一闪而过的。被释放。苹果公司没有提供非史前的libstdc
,而是编写了自己的标准库实现与LLVM和Clang项目一起使用。using -stdlib=libc++告诉clang使用该libc
标准库实现而不是古老的libstdc 。由于libc 是最近写的,它具有operator<<右值引用的重载。



 类似资料:
  • 测试用例: 输入-123//正确 输出-3 intput-1111111111111111111111111111111111//输出不正确 -10 输入-11111//不正确 输出-1010

  • 如下代码为什么输出的结果不是1,2,3,4? 而是输出了错误的结果:1803629872 77304476 1803629872 0

  • 问题内容: 我在C#和Java中发现了一些奇怪的地方。让我们看一下这个C ++代码: 在控制台中,您将看到X = 11(在此处查看结果-IdeOne C ++)。 现在让我们看一下C#上的相同代码: 在控制台中,您将看到1(而不是11!)(在这里查看结果-IdeOne C# 我知道您现在在想什么-“这怎么可能?”,但让我们转到下面的代码。 Java代码: 结果与C#中的结果相同(X = 1,在此处

  • 本文向大家介绍C# 动态输出Dos命令执行结果的实例(附源码),包括了C# 动态输出Dos命令执行结果的实例(附源码)的使用技巧和注意事项,需要的朋友参考一下 本文以一个简单的小例子讲解如何将命令行信息实时的输出到文本框中。仅供学习分享使用,如有不足之处,还请指正。 概述 在C#程序开发过程中,有时需要运行其它的程序并获得输出的结果来进行进一步的处理。一般第三方的程序,主要通过进程来调用,如果能够

  • 在我看来,我的缓冲区包含关于最后一个数据包步骤(路由器->my home)的信息,这些信息解释了为什么TTL值是254以及为什么我用Traceroute找到了相同的两个IP: $>traceroute qwant.com traceroute to qwant.com(194.187.168.99),30跳最大,60字节数据包 172.17.0.1(172.17.0.1)0.026 ms 0.01

  • 主要内容:C#程序结构,编译并执行程序在讲解 C# 的基本语法之前,让我们先来了解一下一个简单的 C# 程序是由哪些部分构成的。一个 C# 程序主要包括以下几个部分: 命名空间声明; 一个类(class); 类方法; 类属性; 一个 Main 方法; 语句和表达式; 注释。 C#程序结构 下面我们通过一个在命令行窗口打印“Hello World”的示例程序,来具体演示一下 C# 程序的组成,代码如下: 运行上面的代码即可在命令行窗口输