• ベストアンサー

コンパイラの違いについて

こんばんはです。 実は、ビジュアルスタジオで組んだCソースをBolrand C++コンパイラで組んでるPCで実行すると、違った結果が出てきてこまってます。 visualstudioでもBolrandでも、ソースのコンパイルはエラーなしでとおります。 しかし、実行すると、結果が違うのです。これって・・・? 結果と言うのはstrcmpでかえってくる数字なのですが、studioでエグゼつくって実行すると、0も1もー1も返ってきて判断分岐できるのですが、Bolrandの方でエグゼつくって実行すると、0しか返ってきません。なので、分岐は0の時だけの対応しかできないのです。 もっとくわしくいいますと、studioの方もBolrandの方もコンパイルはプロントでおこなっており、studioはcl test.c Bolrandはbcc32 test.c と言う具合に行ってます。 もしかして、古さの違いとかってあるのです?? 昔は構造体のコピーってa = bってできなかったではないですか? 今はa = bできますよね。そういう感じなのでしょうか?? ご存知の方いらっしゃいましたらアドバイスいただきたいです。 よろしくおねがいいたします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

既に#1さんが回答していますが改めて。 strcmp()の戻り値が-1になることを期待してはいけません。 つまり、 if(strcmp(name,sub_name) == -1){ ではなく if(strcmp(name,sub_name) < 0){ と書けばよい、ということです。 逆の場合も同様に、1と比較せずに0との大小で判断すればよいのです。

yuki22
質問者

お礼

お返事ありがとうございます。 なるほどです。う~ん、どうやら理解力が足りなかったみたいではずかしいです・・。 私にもわかるくらいにレベルを落としていただいてありがとうございます^^

その他の回答 (4)

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.5

「strcmpは負数か、0か、正数を返す」です。 ビジュアルスタジオのstrcmpが「name < sub_nameの時、-1しか返さない」としても、それはstrcmpの「name < sub_nameの時、負数を返す」と言う仕様に違反している訳ではないのでOKです。 でも、ビジュアルスタジオが-1しか返さないからと言って、if(strcmp(name,sub_name) == -1)と書くのはNGです。 なぜなら、あるコンパイラのstrcmpが「name < sub_nameの時、-128しか返さない」って場合に、そのコンパイラで動かすとちゃんと動きません。 もちろん、そのコンパイラのstrcmpが返す-128も「負数の1つ」なのでstrcmpの「name < sub_nameの時、負数を返す」と言う仕様に違反している訳ではないのでOKです。 >も、そしたらif(strcmp(name,sub_name) != 0)とかの代わりの判断ってなにがよいのでしょう?? 繰り返しますが「strcmpは負数か、0か、正数を返す」です。 これを言い換えれば、以下のようになります。 strcmp(s1,s2)の結果、返される値は s1がs2より小さい時:負の最小値~-1までの間の、負の数の不定の値が返る s1がs2と等しい時:0が返る s1がs2より大きい時:1~正の最大値までの間の、正の数の不定の値が返る つまり、if文で許されるのは、以下の書き方だけです。 if(strcmp(name,sub_name) != 0) if(strcmp(name,sub_name) == 0) if(strcmp(name,sub_name) < 0) if(strcmp(name,sub_name) <= 0) if(strcmp(name,sub_name) > 0) if(strcmp(name,sub_name) >= 0) 簡単に言えば「0とだけ大小比較、一致比較、不一致比較するのだけ許されている」って事です。 比較する相手に-1とか1とかは使ってはいけません。

yuki22
質問者

お礼

お返事ありがとうございます。 うう・・、こんなに丁寧にありがとうございます。 とってもわかりやすかったです。 アドバイスいただいたことを忘れずに生かさせていただきます。 ありがとうございました^^

noname#22058
noname#22058
回答No.3

> 結果と言うのはstrcmpでかえってくる数字 そこのソースコードを見せてくださると、 いちばん手っ取り早いでしょう。

yuki22
質問者

お礼

お返事ありがとうございます。 うう・・、ソースはお試しでつくったので消してしまったのです・・。 でも、 #include <string.h> void main(){ char name[256]; char sub_name[256]; gets(name);//ABCと入力 gets(sub_name);//DEFと入力 if(strcmp(name,sub_name) == 0){ printf("同じ\n"); } if(strcmp(name,sub_name) == -1){ printf("nameが上\n"); } } こんな感じです。 studioではうまくいったのですが、Bolですと表示されません。 うう・・・、コンパイラ依存というやつなのでしょうか^^;

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.2

ソースをみてないので、想像ですが、その比較する文字列の終端NULLが、きちんと保証されていないことが、考えられます。 たぶん、その領域の初期化をきちんと行っていないことが、原因のような気がします。 main() { int a; if (a==0){   YES }else{   NO } } このような、コーディングは、aの初期化をきちんと行っていません。 YESになるかNOになるかは、コンパイラに依存します。 visualstudioでYESになり、BolrandでNOになるかもしれませんし、 ならないかも知れません。 いずれにせよ、このようなコードは、行うべきではありません。

yuki22
質問者

お礼

お返事ありがとうございます。 初期化はしてあります^^ でも、コンパイラに依存しちゃうのですね・・。 アドバイスありがとうございました。

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.1

strcmpの戻り値をprintfなどで表示してみましょう。 「strcmpは-1、0、1を返す」は間違いです。正しくは 「strcmpは負数、0、正数を返す」です。 ビジュアルスタジオのstrcmpが-1、0、1だけを返すからと言って、Bolrandのstrcmpが-1、0、1だけを返すとは限りません。 もし「if (strcmp(s1,s2) == -1)」や「if (strcmp(s1,s2) == 1)」と書くと、Bolrandでは意図した結果になりません。 実際、Bolrandでstrcmp("ABC","abc")は-1ではなく-32が返されます。 なお、strcmp("ABC","BCD")は-1を返しますが、それは「偶然」です。 strcmpの結果を1や-1と等しいか比べてはいけません。

yuki22
質問者

お礼

お返事ありがとうございます。 偶然っていったい・・? strcmpで文字比較して、1返ってきた数字で判断かけてはいけなかったのでしたか^^; でも、Cではstrcmpで比較ですよね?? コンパイラによってちがうのですか・・。 でも、そしたらif(strcmp(name,sub_name) != 0)とかの代わりの判断ってなにがよいのでしょう??