2011-10-22 3 views
1

C에서 트리를 구현했으며 이제 래퍼 트리 집합을 정의하려고합니다. tree.c에 반복자를 얻을 수GCC 최적화 도구를 사용하는 초기화되지 않은 경고

typedef struct tree_iter_t { 
    void *current; 
    tree_t *tree; 
    unsigned char info : 2; 
} tree_iter_t; 

및 기능 : 나는 tree.h 내 나무에 대한 반복자를

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 내 트리 세트 반복자를 정의 내가 gcc -Wall -c -combine tset.c tree.c 컴파일 할 때

struct tset_t { 
    tree_t *tree; 
}; 

tset_iter_t tsiterator(tset_t *ts) { 
    tset_iter_t it; 
    it.iter = titerator(ts->tree); 
    return it; 
} 

, 나는 아무런 문제가 없지만, 내가 -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 회선 (tree 함수를 호출하기위한 일반적인 함수 호출 오버 헤드)입니다. gcc -O2 -S -combine tset.c tree.c 나에게 경고, 인라인 titerator을주고,이 생산 :

tset_iter_t tsiterator(tset_t *ts) { 
    tset_iter_t it; 
    tree_iter_t i = titerator(ts->tree); 
    it.iter = i; 
    return it; 
} 

가 더 문제가 없었다 : I가 구현을 변경

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 

. 첫 번째 경우에서 GCC가 최적화 (또는 분석)되는 이유는 무엇입니까?

감사합니다.

+0

'tree_iter_t it;'그리고'it.tree = t;'. 'it.tree'는 어디에 있습니까? 왜 진짜 코드를 게시하지 않는거야? – cnicutar

+0

첫 번째 코드 블록에서 * t * tree 여야합니까? –

+0

오타. 나는 그것을 고쳤다. – Nick

답변

1

경고는 버그라고 생각합니다. 어떤 gcc를 사용하고 있습니까? gcc 4.0과 4.2로 (필자가 단일 파일을 컴파일 할 때) 나를 위해 발생하지 않습니다.

다음은 최적화 된 어셈블러의 주석 버전입니다. 여기에 할당되지 않은 것을 볼 수 없기 때문에 경고가 옳지 않다고 생각합니다. 나는 나무 구조에 대해 짐작했다.

tsiterator: 
    pushl %ebp 
    movl %esp, %ebp 
    movl 12(%ebp), %edx ; edx has pointer to ts 
    pushl %ebx 
    movl 8(%ebp), %eax ; eax has pointer to retval 
    movl (%edx), %ecx ; ecx has ts->tree (?) 
    movl 4(%ecx), %edx ; edx has ts->tree->min (?) 
    movl %ecx, 4(%eax) ; store ts->tree into retval->iter->tree 
    cmpl $1, %edx  
    movl %edx, (%eax) ; store ts->tree->min into retval->iter->current 
    ;; This and the cmpl instruction above is all 
    ;; handling the bitmasking for retval->iter->info. 
    ;; Probably would be more efficient to not use a 
    ;; bit mask here, as the compiler could remove the 
    ;; second "and" and "or" instructions. 
    movzbl 8(%eax), %edx ; get current value of retval->iter->info 
    sbbl %ebx, %ebx ; ebx = 0 if unsigned edx < 1, else -1 
    andl $3, %ebx ; mask off new value    
    andl $-4, %edx ; mask off old value 
    orl  %ebx, %edx ; combine old | new  
    movb %dl, 8(%eax) ; store combined into retval->iter->info 
    popl %ebx 
    popl %ebp 
    ret $4 

편집 : 컴파일러 신중 tree_iter_t.info 랜덤 초기화 쓰레기의 상부 6 개 비트를 유지합니다.

+0

gcc 4.4.5 – Nick

0

gcc가 특정 필드 tree에 대해 불평하는 이유를 알지 못했지만 함수에서 반환하는 구조의 일부가 초기화되지 않았다고합니다. 사실 기본적으로 변수의 한 필드 만 초기화하면 다른 변수는 자동으로 0으로 초기화됩니다. 귀하의 경우에는 가장 쉬운 C99의 지정된 이니셜 라이저를 사용하는 것입니다

tree_iter_t it = { .tree = t }; 

을하고 당신은 또한 나중에 해당 필드에의 할당은을 건너 뛸 수 있습니다.

+0

"함수에서 반환하는 구조체의 일부가 초기화되지 않았습니다"- 어떤 부분이 있습니까? – Nick

+0

@Nick, 부분의 다른 비트는'info'와 아마도 다른 패딩에 대응합니다. –