- ベストアンサー
コンパイラの違いについて
こんばんはです。 実は、ビジュアルスタジオで組んだ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できますよね。そういう感じなのでしょうか?? ご存知の方いらっしゃいましたらアドバイスいただきたいです。 よろしくおねがいいたします。
- yuki22
- お礼率83% (159/190)
- C・C++・C#
- 回答数5
- ありがとう数5
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
既に#1さんが回答していますが改めて。 strcmp()の戻り値が-1になることを期待してはいけません。 つまり、 if(strcmp(name,sub_name) == -1){ ではなく if(strcmp(name,sub_name) < 0){ と書けばよい、ということです。 逆の場合も同様に、1と比較せずに0との大小で判断すればよいのです。
その他の回答 (4)
- chie65536
- ベストアンサー率41% (2512/6032)
「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とかは使ってはいけません。
お礼
お返事ありがとうございます。 うう・・、こんなに丁寧にありがとうございます。 とってもわかりやすかったです。 アドバイスいただいたことを忘れずに生かさせていただきます。 ありがとうございました^^
> 結果と言うのはstrcmpでかえってくる数字 そこのソースコードを見せてくださると、 いちばん手っ取り早いでしょう。
お礼
お返事ありがとうございます。 うう・・、ソースはお試しでつくったので消してしまったのです・・。 でも、 #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)
ソースをみてないので、想像ですが、その比較する文字列の終端NULLが、きちんと保証されていないことが、考えられます。 たぶん、その領域の初期化をきちんと行っていないことが、原因のような気がします。 main() { int a; if (a==0){ YES }else{ NO } } このような、コーディングは、aの初期化をきちんと行っていません。 YESになるかNOになるかは、コンパイラに依存します。 visualstudioでYESになり、BolrandでNOになるかもしれませんし、 ならないかも知れません。 いずれにせよ、このようなコードは、行うべきではありません。
お礼
お返事ありがとうございます。 初期化はしてあります^^ でも、コンパイラに依存しちゃうのですね・・。 アドバイスありがとうございました。
- chie65536
- ベストアンサー率41% (2512/6032)
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と等しいか比べてはいけません。
お礼
お返事ありがとうございます。 偶然っていったい・・? strcmpで文字比較して、1返ってきた数字で判断かけてはいけなかったのでしたか^^; でも、Cではstrcmpで比較ですよね?? コンパイラによってちがうのですか・・。 でも、そしたらif(strcmp(name,sub_name) != 0)とかの代わりの判断ってなにがよいのでしょう??
関連するQ&A
- コンパイル環境の違いによる、浮動少数点の違い
不動少数(float)を使った、c言語の演算プログラムを作っています。 Aマシン(CentOS5, gcc3.4)でコンパイルした、"test_a.so"と"test_a.a"について、 Aマシンで実行した結果、両者の結果は一致します。 Bマシン(Fedora5, gcc3.0)でコンパイルした、"test_b.so"と"test_b.a"について、 Bマシンで実行した結果、両者の結果は一致します。 Aマシンで実行した結果、両者の結果が異なります。 結果の比較をすると、以下のようになります。 "test_a.so"=="test_a.a"!="test_b.so"!="test_b.a" (1)コンパイル環境と実行環境が違うと、浮動少数の演算に違いがでることがありますか? (2)コンパイル環境と実行環境が違うと、so と aに違いがでることがありますか? 上記2点について、ご存知の方いらっしゃいましたら教えてください。 お願い致します。
- ベストアンサー
- C・C++・C#
- コンパイル ./aと./a.out の違い
ほんとにcの初心者なのですが、 今Tera Termを使って、ソースを書いて、コンパイル、実行をしているのですが、 例えばtest.cというファイルを gcc test.c とやってコンパイルして、 a.outというファイルができます。 それを./aとやれば実行できると聞いてやってみたのですができません。 ./a.outはできるのですが なぜなのでしょうか??
- 締切済み
- C・C++・C#
- フリーのCコンパイラに関して
今、ボーランドのCコンパイラを使用しているのですが、ボタンに一つでコンパイルして実行するのではなくて、コマンドプロントで、これから行う作業を入力して、 実行することは出来ますか? 他のフリーソフトで出来るものがあれば教えて下さい。
- ベストアンサー
- フリーウェア・フリーソフト
- フリーのコンパイラを探しています
PC上で動作するフリー(若しくは無償で手に入れば期間限定版でも良いです)のCコンパイラ(C++もあれば尚可)を探しています。 目的は、あるサイトから取得した暗号化を行うソースをコンパイル&実行する為です。しかしながら、そのソースはかなり前にPC-98(NEC)で Turbo Cで確認したもので、int型が2バイトであることを前提にしています。試しにBorlandのコンパイラ(BCC32)でコンパイル&実行してもこちらの期待した結果は得られませんでした。(int型をshort型に変更しコンパイルしてもだめでした) 上記の条件にあてはまるものでLSC-Cがありますが、LSC-Cでコンパイルするとメモリ不足となり、コンパイルが異常終了してしまいます。 int型を2バイトとして扱うことのできるコンパイラをLSC-C以外にご存じでしたら教えていただけませんでしょうか。
- ベストアンサー
- C・C++・C#
- C90とC99の計算結果の違い?
C言語の質問です。 gcc version 4.3.2 (Ubuntu 4.3.2-1ubuntu12) 以下のプログラムをgccでコンパイル・実行すると(1)に入り,"a"が出力されます。unsigned intの計算なのでラップアラウンドが生じtest=4294716272となるのは私の期待どおりです。 ただ、gcc -std=c99でコンパイル・実行すると(2)に入り,"b"が出力されました。c99でコンパイル・実行すると計算結果がなぜ異なっているのかが分かりません。 long test = 0; unsigned int x = 184; unsigned int y = 251208; test = (x-y); if(test == 4294716272){ printf("a");// (1) }else if(test == -251024){ printf("b"); // (2) }
- ベストアンサー
- C・C++・C#
- コンパイラが見つかりません。
いつも教えて頂きありがとうございます。 C#の勉強を始めました。 コードは下記の通りです。 using System; class Data{ public static void main() { int a; int b; a=2; b=3; a=b; Console.WriteLine(a); } } このコードに間違いないのですが 検索してもどうやってコンパイル(実行) するのか分りません。 ご回答の程、宜しくお願い申し上げます。
- ベストアンサー
- C・C++・C#
- コンパイラーの不具合?
AIX(5.3)の環境でプログラムソースをコンパイルし実行したところ、 コンパイラーのバージョンの違いによる、挙動の違いを発見しました。 これは、コンパイラーの不具合なのでしょうか? コンパイラーのバージョンは、vacpp 6.0とvacpp 9.0です。 サンプルソースコードと実行結果は以下の通りです <sample.c> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> int aaa( char * a, char *b,char *c,... ) { va_list arglist; char *temp; printf("1.a=%x\n",&a); printf("2.b=%x\n",&b); printf("----------------------\n"); va_start( arglist, a ); printf( "3.%x=%x=%s\n",arglist,*(char **)arglist,*(char **)arglist); for( ; (temp = va_arg( arglist, char * )) != 0; ){ printf( "%x=%x=%s\n", arglist, temp, temp ); } va_end( arglist ); printf("----------------------\n"); va_start( arglist, b ); printf( "3.%x=%x=%s\n",arglist,*(char **)arglist,*(char **)arglist); for( ; (temp = va_arg( arglist, char * )) != 0; ){ printf( "%x=%x=%s\n", arglist, temp, temp ); } va_end( arglist ); printf("----------------------\n"); va_start( arglist, c ); printf( "3.%x=%x=%s\n",arglist,*(char **)arglist,*(char **)arglist); for( ; (temp = va_arg( arglist, char * )) != 0; ){ printf( "%x=%x=%s\n", arglist, temp, temp ); } va_end( arglist ); return 0; } int main(void) { aaa("1","A","B","C","D",0); return 0; } <コンパイルコマンド> xlC -o sample sample.cpp <バージョン6.00実行結果=正しい結果> 1.a=2ff22568 2.b=2ff2256c ---------------------- 3.2ff2256c=10002460=A 2ff22570=10002460=A 2ff22574=10002462=B 2ff22578=10002464=C 2ff2257c=10002466=D ---------------------- 3.2ff22570=10002462=B 2ff22574=10002462=B 2ff22578=10002464=C 2ff2257c=10002466=D ---------------------- 3.2ff22574=10002464=C 2ff22578=10002464=C 2ff2257c=10002466=D <バージョン9.00実行結果=正しい結果> 1.a=2ff22a48 2.b=2ff22a4c ---------------------- 3.2ff22a4c=10000a30=A ←おかしい 2ff22a54=10000a32=B 2ff22a58=10000a34=C 2ff22a5c=10000a36=D ---------------------- 3.2ff22a50=10000a32=B ←ただしい 2ff22a54=10000a32=B 2ff22a58=10000a34=C 2ff22a5c=10000a36=D ---------------------- 3.2ff22a54=10000a34=C ←おかしい 2ff22a5c=10000a36=D
- ベストアンサー
- C・C++・C#
- Cコンパイラ(gcc)について
はじめまして。 C言語のコンパイラについてお尋ねしても宜しいでしょうか。 以下のファイルが存在します。 ・test.c(C言語のソースファイル) ・test.exe(上記ソースをコンパイルしたもの。Windows環境で現在稼動してます) test.cの中身を一部変更し、コンパイルする必要があるのですが、 (恥ずかしながら、コンパイルした人間はもう居ないので) 何のコンパイラを使ったか、判りません。 コンパイルするときに使用したであろうコマンドがあります。 gcc test.c -WALL -03 -o test.exe 察するに、gccというコンパイラを使用したと思い MiniGW (http://yanchde.gozaru.jp/mingw/wingw_start.html) を使用してコンパイルをしてみました。 コンパイルは通るのですが、出来上がるexeファイルのサイズが 非常に小さいです。 (オリジナルのtest.exeは500KB以上ありますが、今回コンパイルで出来たものは40kbほどです) この場合、、オリジナルのtest.exeと今回コンパイルしたexeは 異なる挙動をする可能性はありますでしょうか。。 初歩的な質問で恐縮ですが、どうかご教授頂けると、幸いです。
- 締切済み
- C・C++・C#
- GNUコンパイラとIntelコンパイラの違いについて
今回fortranとC言語で書かれたWindows用プログラムをLinux用に移植することになりました。GNUのコンパイラを使用し無事コンパイルできたので実行したのですが"Segmentation fault"となりうまく実行できませんでした。そこで試しにIntelのコンパイラを使用しコンパイルしてみたところGNUのときとは違い"Segmentation fault"とは出ず、プログラム内のエラーチェックに引っかかり止ってしまいました。同じソースコードにもかかわらず止まる箇所が異なります。 今まで考えたことがなかったのですがGNUとIntelのコンパイラの違いはなんなのでしょうか?また、この二つ以外にいいコンパイラはあるのでしょうか?
- ベストアンサー
- C・C++・C#
- コンパイラによってエラーが出たり出なかったり
構造体をポインタでつなぐリスト構造を使ったソースを書いて、Borland C++ Compiler 5.5 でコンパイルしたものを実行するとエラーで止まってしまいました。 コンパイル時には何も警告が出ませんでした。 しかし、ソースを何度見てもバグらしいコードが見つからなかったので、試しに Microsoft .NET Framework SDK でコンパイルしてみたところ、こちらも警告も出ずにコンパイルが通って、実行してみたらこんどは正常に動作しました。 コンパイラによって、実行時にエラーが出たり出なかったりするということは初めてなのでその原因を知りたくて質問しました。 どういった場合にこのようなことが起こるのでしょうか。 Borland C++ で出たエラーは、おそらくセグメントエラーだと思います。 今のところ正常に動いているのですが、なにかデンジャラスなコードを書いてしまった気がして気持ち悪いです。
- ベストアンサー
- C・C++・C#
お礼
お返事ありがとうございます。 なるほどです。う~ん、どうやら理解力が足りなかったみたいではずかしいです・・。 私にもわかるくらいにレベルを落としていただいてありがとうございます^^