OS Xでは、単純なC ++プログラムが誤った結果を返します(これはコマンドラインオプション 'c ++ 03'と 'c ++ 11'の結果です)

バッドマンチャイルド:

この単純なプログラム(Linuxでコンパイルした場合)は、コンパイルされているかどうかに基づいて、2つの異なる答えを正しく返します-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

最初は16進数のアドレスを出力し、2番目は「Hello」を出力します。これは正しい動作であり、演算子<<は2つの異なるものに解決されるためです(C ++ 03には右辺値参照がないため、そのままです)。

次に、OS Xで同じことを試してください。


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

(これにより、16進数の出力が正しく生成されます。)


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

(おっと... 16進数の出力です... 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で異なる結果が得られる理由を、回答の1つで以下に示します。

ジョナサンウェイクリー:

まず、予想される動作の違いは、operator<<(std::ostream&, const char*)オーバーロード(実際には関数テンプレートの特殊化ですが、今のところ気にしない)には型のパラメーターがstd::ostream&あり、左辺値参照は左辺値にしかバインドできないためです。この例では、ストリームは右辺値なのでそのオーバーロードは使用できません。C ++ 03 std::ostream::operator<<(const void*)では、メンバー関数右辺値オブジェクトで呼び出すことできるため、唯一の実行可能なオーバーロードはメンバー関数であることを意味し、文字列はvoid*16進数のアドレスとして書き出されます。C ++ 11には、operator<<(std::ostream&&, const T&)右辺値ストリームへの書き込みを許可し、operator<<(std::ostream&, const char*)オーバーロードに転送する新しい関数テンプレートがあるため、16進アドレスではなく文字列が出力されます。

GNU / Linuxでは、ごく最近のGCCリリースを使用していると思われます。これは、コンパイラー(g ++)と標準ライブラリー(libstdc ++)の両方でC ++ 11をかなりサポートしているため、operator<<(std::ostream&&, const T&)オーバーロードとすべてが機能します。

OS Xでは、おそらくGCCの標準ライブラリであるlibstdc ++でClangを使用しています。Xcodeにはデフォルトで古いバージョンのGCC(4.2)が同梱されており、GCC 4.2の標準ライブラリはC ++ 11をサポートしていないoperator<<ため、右辺値ストリームのオーバーロードはありませんを使用する-std=c++0xと、ClangはC ++ 11言語機能(右辺値参照など)をサポートするように指示されますが、GCC 4.2のライブラリが魔法のようにC ++ 11コードを成長させることはありません。解放された。先史時代ではないlibstdc ++を出荷するのではなく、Appleは代わりに独自の標準ライブラリ実装を作成して、LLVMおよびClangプロジェクトに対応しました。を使用する-stdlib=libc++と、clangに、古代のlibstdc ++ではなく、そのlibc ++標準ライブラリ実装を使用するように指示します。libc ++は最近書かれたので、operator<< 右辺値参照のオーバーロード。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ