Cでツリーを実装しましたが、今ではラッパーツリーセットを定義したいと考えています。私はtree.hの私のツリーのイテレータを持っている:GCCオプティマイザを使用した初期化されていない警告
typedef struct tree_iter_t {
void *current;
tree_t *tree;
unsigned char info : 2;
} tree_iter_t;
とtree.cでイテレータを取得するための機能:
tree_iter_t titerator(tree_t *t) {
tree_iter_t it;
it.current = t->min;
if (t->min) it.info = 0;
else it.info = 3;
it.tree = t;
return it;
}
私は警告なしで-Wall -O2
でこれをコンパイルすることができます。
typedef struct tset_t tset_t;
typedef struct tset_iter_t {
tree_iter_t iter;
} tset_iter_t;
とtset.c.でそれを取得する機能を次のように私の木のセットのために、私はtset.hの私のツリーセット・イテレータを定義し
struct tset_t {
tree_t *tree;
};
tset_iter_t tsiterator(tset_t *ts) {
tset_iter_t it;
it.iter = titerator(ts->tree);
return it;
}
私はgcc -Wall -c -combine tset.c tree.c
でコンパイルすると、私は問題がないが、私は-O2
を追加するとき、私は、return文に警告を得る:warning: ‘it.iter.tree’ is used uninitialized in this function
を。なぜGCCはこれに問題がありますか?私は明白な何かを欠いていますかそれは私に初期化されて見えます。私は何が起こっていたかの感覚を取得しようとするgcc -S -O2 tset.c
を走った、GCCは警告を与えておらず、これを生産:
tsiterator:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $36, %esp
movl 12(%ebp), %edx
movl 8(%ebp), %ebx
leal -20(%ebp), %eax
movl (%edx), %edx
movl %eax, (%esp)
movl %edx, 4(%esp)
call titerator
movzbl -12(%ebp), %edx
movzbl 8(%ebx), %eax
andl $3, %edx
andl $-4, %eax
orl %edx, %eax
subl $4, %esp
movb %al, 8(%ebx)
movl -16(%ebp), %eax
movl %eax, 4(%ebx)
movl -20(%ebp), %eax
movl %eax, (%ebx)
movl %ebx, %eax
movl -4(%ebp), %ebx
leave
ret $4
私は、最適化は、いくつかの奇妙に見えるコードを生成することができます知っているが、一体何がここで起こっています! ?他のすべての(最適化された)ラッパー関数は、10-ishのアセンブリ行です(ツリーの関数を呼び出すための通常の関数呼び出しオーバーヘッド)。 gcc -O2 -S -combine tset.c tree.c
は私に警告、インラインtiteratorを与え、これを生産:
tsiterator:
pushl %ebp
movl %esp, %ebp
movl 12(%ebp), %edx
pushl %ebx
movl 8(%ebp), %eax
movl (%edx), %ecx
movl 4(%ecx), %edx
movl %ecx, 4(%eax)
cmpl $1, %edx
movl %edx, (%eax)
movzbl 8(%eax), %edx
sbbl %ebx, %ebx
andl $3, %ebx
andl $-4, %edx
orl %ebx, %edx
movb %dl, 8(%eax)
popl %ebx
popl %ebp
ret $4
私は実装を変更する場合:
tset_iter_t tsiterator(tset_t *ts) {
tset_iter_t it;
tree_iter_t i = titerator(ts->tree);
it.iter = i;
return it;
}
それは問題はなかったです。最初のケースでGCCの最適化(または解析)とは何ですか、なぜそれが私に警告を与えていますか?
ありがとうございました。
'tree_iter_t it;'と 'it.tree = t;'です。 'it.tree'はどこですか?なぜ実際のコードを投稿していないのですか?最初のコードブロックの – cnicutar
は、* t * treeであるべきですか? –
Typo。それを私が直した。 – Nick