アプリ版:「スタンプのみでお礼する」機能のリリースについて

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

A 回答 (3件)

> 変数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

この回答への補足

ご返答ありがとうございます

その後、いろいろ試してみたのですがfor文をwhile文に変更してみた結果正常に動作しました。

for( ; (temp = va_arg( arglist, char * )) != 0; ){
↓↓↓
while( (temp = va_arg( arglist, char * )) != 0 ){

またfor文のままでもC++とせずCでコンパイルしたところ正常に動作します。

C++でのfor文の使用方法に問題があるのでしょうか?

補足日時:2008/11/26 09:48
    • good
    • 0
この回答へのお礼

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

お礼日時:2008/11/26 13:41

全然関係ないですけど, このコードって未定義動作の嵐のような気がする.


とりあえず
・ポインタの値を %x で出力しようとしてる
・arglist を無理矢理 char ** にキャストしてる
・可変引数関数に対する実引数の型がおかしい (最後の 0)
あたりは気付く.
    • good
    • 0

va_start()は、引数リストで...の直前の変数(サンプルコードの中ではc)にしか使えません。

それ以外の変数を対象にした場合の動作は保証されていないはずです。
したがって、期待したとおりの挙動にならなくても文句は言えません。

この回答への補足

ご回答ありがとうございます

変数cについても実行結果が違うのですが、この結果もありうると言うことでしょうか?

<バージョン6.00実行結果=正しい結果>
----------------------
3.2ff22574=10002464=C
2ff22578=10002464=C
2ff2257c=10002466=D

<バージョン9.00実行結果=正しくない結果>
----------------------
3.2ff22a54=10000a34=C ←おかしい
2ff22a5c=10000a36=D

補足日時:2008/11/25 21:49
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!