AIXの環境でコンパイルしたプログラムのコンパイラーバージョンによる挙動の違い

このQ&Aのポイント
  • AIX(5.3)の環境でプログラムソースをコンパイルし実行したところ、コンパイラーのバージョンの違いによる、挙動の違いを発見しました。
  • コンパイラーの不具合なのか、コンパイラーバージョンによる挙動の違いなのか確認したいです。
  • コンパイラーのバージョンは、vacpp 6.0とvacpp 9.0です。サンプルソースコードと実行結果を参考にしてください。
回答を見る
  • ベストアンサー

コンパイラーの不具合?

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

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

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.2

> 変数cについても実行結果が違うのですが、この結果もありうると言うことでしょうか? あり得るんじゃないでしょうか。 どうしてそうなるのかをちゃんと説明するには、コンパイラが生成したバイナリを逆アセンブルしてみる必要があるでしょう。 va_start( arglist, a );~va_end( arglist );とva_start( arglist, b );~va_end( arglist );のコードを消して、cだけを対象にva_start()を使った場合にも結果が異なるようならコンパイラの不具合を疑うところですが。 ちなみに、GCCでコンパイルしたところちゃんとva_start()について警告が出て、下記のような結果になりました。 warning: second parameter of 'va_start' not last named argument 1.a=bffff688 2.b=bffff68c ---------------------- 3.bffff694=2fbc=C bffff698=2fbc=C bffff69c=2fc0=D ---------------------- 3.bffff694=2fbc=C bffff698=2fbc=C bffff69c=2fc0=D ---------------------- 3.bffff694=2fbc=C bffff698=2fbc=C bffff69c=2fc0=D

kumazoro
質問者

お礼

解決しました! コンパイラーのパッチが出ていたので、それをインストールするとこの現象がでなくなりました。 お騒がせしました。

kumazoro
質問者

補足

ご返答ありがとうございます その後、いろいろ試してみたのですがfor文をwhile文に変更してみた結果正常に動作しました。 for( ; (temp = va_arg( arglist, char * )) != 0; ){ ↓↓↓ while( (temp = va_arg( arglist, char * )) != 0 ){ またfor文のままでもC++とせずCでコンパイルしたところ正常に動作します。 C++でのfor文の使用方法に問題があるのでしょうか?

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

全然関係ないですけど, このコードって未定義動作の嵐のような気がする. とりあえず ・ポインタの値を %x で出力しようとしてる ・arglist を無理矢理 char ** にキャストしてる ・可変引数関数に対する実引数の型がおかしい (最後の 0) あたりは気付く.

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.1

va_start()は、引数リストで...の直前の変数(サンプルコードの中ではc)にしか使えません。それ以外の変数を対象にした場合の動作は保証されていないはずです。 したがって、期待したとおりの挙動にならなくても文句は言えません。

kumazoro
質問者

補足

ご回答ありがとうございます 変数cについても実行結果が違うのですが、この結果もありうると言うことでしょうか? <バージョン6.00実行結果=正しい結果> ---------------------- 3.2ff22574=10002464=C 2ff22578=10002464=C 2ff2257c=10002466=D <バージョン9.00実行結果=正しくない結果> ---------------------- 3.2ff22a54=10000a34=C ←おかしい 2ff22a5c=10000a36=D

関連するQ&A

  • sscanfって・・・。

    #include<stdio.h> main() { char str[] = "aiueokkakikukekossashisusesottstituteto"; char a[20], b[20], c[20], d[20]; sscanf(str,"%[^k],%[^s],%[^t],%[^\0]",a,b,c,d); printf("%s\n",a); printf("%s\n",b); printf("%s\n",c); printf("%s\n",d); } 上のプラグラムでaはaiueoとちゃんと出力されるのですがb,c,dがちゃんと出力されないのはなぜでしょうか?与えられた文字を代える以外によい方法があれば教えてください。

  • プログラミング教えてください!!!お願いします。

    プログラミング教えてください!!!お願いします。 次の文が実行されると何がどのようにプリントされるか。何もプリントされない時は「なし」と記せ。 また、途中に「ブランク」が入る場合は、”b”と記せ。 (1) int func1(), func2(); int data = 100; main() { int w = 1; static x =10; printf("** %d, %d, %d\n" ,w,x,data); func1(); printf("** %d, %d, %d\n" ,w,x,data); } int func1(){ int w = 2; static int x = 20: printf("*** %d, %d, %d\n", w, x, data); x += 10; func2(); printf("*** %d, %d, %d\n" , w,x,data); x *= 2; data = data - x; } int func2() { int w = 3; static int x = 30; printf("**** %d, %d, %d\n" ,w,x,data); data -= x; } (2) int func1(char *, char *, char *); int func2(char *, char *, char *); main() { char sta[20], stb[20], stc[20], std[20]; int i=0; func1("abc","xyz",sta); printf("%d -- %s\n" ,++i,sta); func1("123","456",stb); printf("%d -- %s\n" ,++i,stb); func1(sta,stb,stc); printf("%d -- %s\n" ,++i,stc); func2(sta,stb,std); printf("%d -- %s\n" ,++i,std); } int func1(char *a, char *b, char *c){ while(*a) *c++ = *a++; while(*b) *c++ = *b++; * c = 0x00; } int func2(char *a, char *b, char *c){ int i = 0; while(*b){ if(i%2 == 0) *c++ = *a++; else *c++ = *b++; i++; } *c = 0x00; }

  • 複数の戻り値

    関数にポインタを渡して、結果を格納してもらう方法で 複数の戻り値を得ようとしたのですがうまく行きません どうしたら複数戻せますか? ---ソース--- #include <stdio.h> #include <stdlib.h> void check(int a,char *b,char *c); void main(void){ int a; char *b,*c; int i; char *va[5]={"2","3"}; for(i=0;i<5;i++){ //ここ何とかなったらwhileにしとこ if(va[i]!=NULL){ a=atoi(va[i]); check(a,b,c); printf("%s%s\n",b,c); } } } void check(int a,char *b,char *c){ switch(a){ case 0: b="0:×\n"; c="0:○\n"; break; case 1: b="1:×\n"; c="1:○\n"; break; case 2: b="2:×\n"; c="2:○\n"; break; case 3: b="3:×\n"; c="3:○\n"; break; case 4: b="4:×\n"; c="4:○\n"; break; } }

  • このプログラミングのいけないところは?

    こういうプログラムを作ったんですけど、なぜか正常に作動しません!理由をおしえてください!!!!!! お願いしますーーー!!ちなみに内容はドイツ語です。 #include "stdafx.h" void tyuusinn(); void head_1(); void head_2(); int main() { while(1){ tyuusinn(); } return 0; } void tyuusinn() { int a; printf("(1)→sein,haben,werdenについて\n"); printf("(2)→定冠詞\n"); printf("表示したい項目を選んでください\n"); scanf_s("%d",&a); if(a == 1){ head_1(); } else if(a == 2){ head_2(); } } void head_1() { char a[90] = " sein haben werden"; printf("%6s\n",a); printf("------------------------------\n"); char b[90] = "ich bin habe werde"; printf("%6s\n",b); char c[90] = "du bist hast wirst"; printf("%6s\n",c); char d[90] = "er ist hat wird"; char e[90] = "wir sind haben werden"; char f[90] = "ihr seid habt werdet"; char g[90] = "sie sind haben werden"; printf("%6s\n%6s\n%6s\n%6s\n",d,e,f,g); return; } void head_2() { char a[90] = "der des dem den"; char b[90] = "die der der die"; char c[90] = "das des dem das"; char x[90],y[90],z[90]; printf("男性名詞は?\n"); scanf("%s",&x); if(x == a) printf("正解です。\n"); else printf("不正解!正解は%sです。\n",a); printf("女性名詞は?\n"); scanf("%s",&y); if(y == b) printf("正解です。\n"); else printf("不正解!正解は%sです。\n",b); printf("中性名詞は?\n"); scanf("%s",&z); if(z == c) printf("正解です。\n"); else printf("不正解!正解は%sです。\n",c); return; }

  • sscanf エラー

    sscanfで整数が読み込めません。 コマンドプロンプトの画面は以下のようです。 文章を入力してください。 aaaa 11 14 aaaa 4201776 4201870 1 以下が実行したコードです。 #include<stdio.h> int main(void){ int a,b,c,i; char name[20]; printf("文章を入力してください。\n"); scanf("%s",x); c=sscanf(x,"%s %d %d",name,&a,&b); printf("%s %d %d %d\n",name,a,b,c); return(0);} aaaa 11 14と表示されるように、御指摘おねがいします。

  • C言語 ソートについて

    #include <stdbool.h> #include <stdio.h> void swap(char *a, char *b) { } bool is_at(char c) { } void justify(char line[], int n) { } int main(void) { char line[] = "a@b@@@c@@d@@@ef@@g"; size_t n = sizeof(line) - 1; justify(line, n); printf("%s\n", line); return 0; } 上の雛形を使って文字列lineに含まれる@以外の文字を文字列の前の方に詰めていくプログラミングを作るという問題を解いていたのですが下のプログラミングまでは出来たのですが最後のjustifyの部分がわかりません 良ければ解答をお願いします #include <stdbool.h> #include <stdio.h> void swap(char *a, char *b) { char temp = *a; *a = *b; *b = temp; } bool is_at(char c) { if(c == '@') { return true; } else { return false; } } void justify(char line[], int n) { for(int i=0;i<n-1;i++) { } } int main(void) { char line[] = "a@b@@@c@@d@@@ef@@g"; size_t n = sizeof(line) - 1; justify(line, n); printf("%s\n", line); return 0; }

  • どこが悪いのか・・・

    初めまして、こんばんわ。 学校の課題で、二次方程式のXの解を求めるC言語のプログラムを作ったのですが 何故か巧く起動しません。 よくわかりません・・・。 是非、何処が悪いのか指摘していただくと嬉しいです。 /*2-10(su210.c)*/ #include <stdio.h> #include <math.h> main() { int a,b,c; float D,x,y; printf("a*x^2+b*x+c=0のときa.b.cを入力して下さい。\n"); printf("a="); scanf("%d",&a); printf("b="); scanf("%d",&b); printf("c="); scanf("%d",&c); if(a=0){ if(b=c=0) printf("xはすべての実数をとる。"); else{ if(c=0&&b!=0) printf("x=0"); else{ if(b=0&&c!=0) printf("解なし。"); else{ if(b!=0&&c!=0) {x=-c/b; printf("x=%f",x);} } } } } else{ if(a!=0){ D=b^2-4*a*c; if(D>0){ x=(-b+sqrt(D))/2/a; y=(-b-sqrt(D))/2/a; printf("判別式はD>0です。\n"); printf("x1=%f\n",x); printf("x2=%f\n",y);} else{ if(D=0){x=-b/2*a;printf("判別式はD=0です。\n");printf("x=%f",x);} else{ if(D<0){printf("判別式はD<0です。\n");printf("解なし。");} } } } } }

  • 出力内容を新しいテキストファイルで保存するには?

    プログラム #include <stdio.h> #include <string.h> main() { char text[100]; char a[20], b[20], c[20], d[20], e[20], f[20]; char fname[20]; int i = 1; FILE *fp; printf("■ファイル名>>"); scanf("%s",fname); fp=fopen(fname,"r"); if((fp = fopen(fname,"r")) == NULL){ printf("ファイルをオープンできませんでした。\n"); return 1; } else{ printf("ファイルをオープンしました。\n"); } while( fscanf(fp, "%s", text) != EOF){ sscanf(text, "%[^,], %[^,], %[^,], %[^,], %[^,], %[^\0]", a, b, c ,d, e, f); printf("%d回目\n",i++); printf("全文:%s\n",text); printf("1つ目:%s\n",a); printf("2つ目:%s\n",b); printf("3つ目:%s\n",c); printf("4つ目:%s\n",d); printf("5つ目:%s\n",e); printf("6つ目:%s\n\n",f); } } テキストファイル ABCD,EFGH,IJKL,MNOP,QRST,UVWXWZ abcd,efgh,ijkl,mnop,qrst,uvwxyz あいうえお,かきくけこ,さしすせそ,たちつてと,なにぬねの,はひふへほ テキストファイルから文字列を読み込み、変換させて出力させた内容を他のテキストファイルに保存するにはどのようにしたらいいのでしょうか?

  • ヘロンの公式を作ったプルグラムなのですが、プログラムの間違いを教えてください。

    プログラムの間違いを教えてください ヘロンの公式を作ったプログラムなんですが・・・ #include <stdio.h> #include <math.h> void main(void) { float a,b,c,s,x; printf("三角形の三辺の長さを入れてください\n"); printf("a="); scanf("%f",&a); printf("b="); scanf("%f",&b); printf("c="); scanf("%f",&c); s=(a+b+c)/2; x= sqrt(s*(s-a)*(s-b)*(s-c)); printf("\n%f",x); }

  • borland bcc55

     次のプログラムと結果を見てください。 a[2]のアドレスと b のアドレスが同じなんですけど、これで、いいのですかね。宜しくお願いします。 0256  #include<stdio.h> main(){ int a[5]; int *pa; int i; int b; b=16; pa=a; for(i=0;i<6;i++){ *pa++=1000+i; printf(" a[%2d]=%x %x\n",i,*pa,pa); ++pa; printf(" &b=%x\n",&b); } return 0; } C:\Users\tadao\2015>2160 a[ 0]=7ffde000 18ff40 &b=18ff50 a[ 1]=1 18ff48 &b=18ff50 a[ 2]=10 18ff50 --------??????????????? &b=18ff50 ------------??????????????? a[ 3]=407cce 18ff58 &b=18ff50 a[ 4]=1c121c8 18ff60 &b=18ff50 a[ 5]=401000 18ff68 &b=18ff50