hlist_for_each, hlist_for_each_safe에 대한 궁금증

시로코의 이미지

리눅스 커널 소스를 살펴보다 보면 hlist_for_each, hlist_for_each_safe가 많이 나옵니다.

#define hlist_for_each(pos, head) \
	for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
	     pos = pos->next)
 
#define hlist_for_each_safe(pos, n, head) \
	for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
	     pos = n)

pos && ({ prefetch(pos->next); 1; }); 여기서 보면 prefetch()는 캐시에 미리 읽어온다는 것 같고,
pos && prefetch(pos->next)만 있으면 되지 왜 1;이 뒤에 붙어있을까요?

pos && ({ n = pos->next; 1; }); 부분에도 n = pos->next;만 있으면 될 것 같은데 1;이 뒤에 붙어있고요.

서지원의 이미지

커널 소스를 본 적은 없지만, 답변을 하자면..

{ a;b;c; ... ; z } 전체는 마지막 z의 값으로 evaluate되게 됩니다. gcc extension이고요.
뒤에 ({ n = pos->next; 1; }) 부분이 항상 1(true)로 evaluate되게 하려고 저렇게 한겁니다. 저 부분은 실행만 되어야지 for loop의 끝나는 조건에 영향을 미치면 안되니깐요.

시로코의 이미지

답변 감사드립니다. gcc extension이라면 gcc extension을 사용하지 않고 일반적인 코드로
({ n = pos->next; 1; })과 똑같은 효과를 내려면 어떻게 해야 할까요?