2017-10-31 20 views
0

私はループのために私を投げかけている問題に遭遇しています。私は、オーバーロードされた演算子がコードの可読性をどのように高めることができるかを説明しようとしていました。そうするために、私は「牛」という特別な意味を持たない単純なクラスを書いた。 Macでコードをコンパイルすると、コンパイルされ、期待通りに実行されます。Macで正しいコードが正しく、Linuxで正しくありません

Linuxのボックス(Ubuntu)でコンパイルされたコードとまったく同じコードもきれいにコンパイルされますが、誤った結果で実行されます。

どこかに明白なものがありますが、私はそれを見ていません。ここ

コードである:

#include <iostream> 
#include <sstream> 
using namespace std; 

class cow { 
public: 
    cow(); 
    cow(int i); 
    int add(int a); 
    int add(string str); 
    int get() const; 
private: 
    int i; 
}; 

cow::cow() { 
    i = 0; 
} 

cow::cow(int j) { 
    i = j; 
} 

int cow::add(string str) { 
    stringstream s; 
    int num; 
    s << str; 
    s >> num; 

    return i += num; 
} 

int cow::add(int a) { 
    return i += a; 
} 

int cow::get() const { 
    return i; 
} 

int main() { 
    cow i(15); 
    cout << i.get() << " : " << i.add(15) << " : " << i.add("-15.0"); 
    return 0; 
} 

コンパイル(g++ -Wall -o cow cow.cpp)は何の警告およびエラーなしを生じず、実行ファイルを作成します。

Linuxボックス利回り上でプログラムを実行する:

$ ./cow 
15 : 30 : 15 

Mac上でC++コンパイラは次のとおりです:

$ g++ --version 
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 
Apple LLVM version 9.0.0 (clang-900.0.38) 
Target: x86_64-apple-darwin16.7.0 
Thread model: posix 
InstalledDir: /Library/Developer/CommandLineTools/usr/bin 

$ ./cow 
15 : 15 : 0 

は、Macの利回り上でプログラムを実行しますLinuxボックスのC++コンパイラは、

です。
$ g++ --version 
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609 
Copyright (C) 2015 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

この現象を引き起こす原因については、Linuxボックスで修正する方法もありますので、ご了承ください。

おかげで、あなたはこの行の未定義の動作に実行している

キース

+0

のような順番で評価する必要があります。これは一般的なバグであり、未定義の動作とシーケンスポイントがあります。 –

答えて

2

1つの式内でインスタンスの状態を複数回変更するため、未定義の動作が発生しています。 C++標準では、この行のiにあなたの呼び出し:

cout << i.get() << " : " << i.add(15) << " : " << i.add("-15.0"); 

は、任意の順序で実行することができます。 Macのコンパイラが期待通りに左から右へコールを実行するのはあなたの運勢です。 信頼できる結果を得るには、

auto a1 = i.get(); 
auto a2 = i.add(15); 
auto a3 = i.add("-15.0); 
cout << a1 << " : " << a2 << " : " << a3; 
+0

ありがとうございます。これは重複した質問だったので、私は検索能力を向上させる必要があるようにも思える。謝罪。 –

+0

正直言って、私は質問を重複としてマークした司会者には全く同意しません。もちろん、参照されている記事ではこのケースを包括的に説明していますが、C++の学習を始めたばかりの人は、「シーケンスポイント」という用語が何を意味するのかわからない場合や、あなたが記述した効果は、シーケンスポイントの概念の誤解の兆候です。 – Jurlie

2

cout << i.get() << " : " << i.add(15) << " : " << i.add("-15.0"); 

それはそれはi.get()i.add(15)i.add("-15.0")を評価して注文するコンパイラ次第です - それはありませんそれらのうちの1つを評価することが別のものの出力を変更しない限り(通常は、ここではiが変更されます)、問題が発生します。

異なるコンパイラ(Linuxではg ++、Macではclang)を使用しているため、それぞれ異なる順序で評価されています。

関連する問題