2010-03-29 4 views
3

사후 증가 연산자의 평가는 어떤 순서로 발생합니까?

std::vector<CMyClass> objects; 
CMyClass list[MAX_OBJECT_COUNT]; 

는이 작업을 수행하는 것이 현명하다

을 감안할 때?

for(unsigned int i = 0; i < objects.size(); list[i] = objects.at(i++)); 

아니면이 루프를 확장해야합니까?

for(unsigned int i = 0; i < objects.size(); i++) 
{ 
    list[i] = objects.at(i); 
} 
+0

'list' 및'objects'에는 어떤 유형이 있습니까? – MSalters

+0

이를 반영하여 질문을 업데이트했습니다. – sum1stolemyname

답변

11

전 정의되지 않은 동작입니다. 에 대한 함수 호출 전후에 list[i]이 평가되는지 (할당의 lh에 대해 lvalue를 제공하는지)는 지정되지 않습니다.

그러므로 개재 서열 포인트없이 i가 (list[i]에서) 액세스 별도로 (i++에서) 수정 된 표현의 다양한 부분의 법적 순서가있다.

이것은 합법적 인 주문 여부와 상관없이 C++ 표준에서 정의되지 않은 동작의 조건입니다. IIRC C 표준은 약간 다른 표현이지만 같은 효과를냅니다.

의심스러운 경우 증가 연산자를 사용하는 식을 쓰지 말고 식의 다른 곳에서는 같은 값을 사용하십시오. 시퀀스 포인트가 있기 때문에 쉼표 연산자 (i++, i++은 괜찮습니다)와 조건부 연산자 (i ? i++ : i--은 괜찮습니다)로 처리 할 수 ​​있지만 그다지 가치가 없습니다. ||&&도 마찬가지이며 p != end_p && *(p++) = something;과 같은 것이 완전히 잘못된 것은 아닙니다. 다른 용도로 사용하면 오랫동안 충분히 보았을 때 대개 일을 망칠 정도의 평가 순서를 찾아 낼 수 있습니다.

복잡한 몸체가있는 for 표현식과 for 루프의 이해 가능성을 제외하고는.

+1

&& 및 || 또한 시퀀스 포인트 (과부하가 아닌 것으로 가정) –

+0

이제 위의 for 루프에서 사용하면 매우 흥미로울 것입니다. –

+0

-1. Un ** 정의 ** 동작? 아니, 확실히. 당신이 정확하게 설명 할 때 두 가지 명령이있을 수 있으며, 표준은 어떤 것이 사용되는지를 문서화하기위한 구현을 요구하지 않습니다. 그러나이 표준은 모든 것을 "정의되지 않은 행동"으로 규정하지는 않습니다. 그것은 명백한 충돌과 코의 악마를 포함하여 어떤 것이 든 더 나쁜 경우입니다. – MSalters

6

의심 스럽다면 이해하기 쉬운 양식을 선호하십시오 (루프를 확장하십시오).

은 (내가 list[i] = objects.at(i++)이 정의되지 않은 동작에 이르게 생각합니다.)

+0

입니다. 나는 노력했다. – sum1stolemyname

1

i++과 같은 표현에서 i을 참조하는 것은 아마 정의되지 않은 동작입니다. 당신이 용기를 사용하고있는 것 같습니다 있기 때문에 그것은 정의되지 않은 동작 수율을 사용하는 것과 동일한 식의 변수를 포스트 증가, 이미 말한 바와 같이, 당신은 아마 ...

list = objects;        // if they're the same type 
list.assign(objects.begin(), objects.end()); // if not 
+1

아니면 최악의 경우 std :: copy를 사용할 수 없다면 (list는 C- 배열인가?). –

1

을 작성할 수 있습니다. 그러나 소형 폼을 유지하려는 경우 시퀀스 포인트를 도입하여 다음을 수행 할 수 있습니다.

for(unsigned int i = 0; i < objects.size(); list[i] = objects.at(i), i++); 
+0

이것은 이전의 "모든 프로그램이 루프의 bodyless로 코딩 될 수 있습니다"처럼 보입니다. – Gorpik

+0

그렇지 않습니까? 이 양식이 IOCCC에서 자주 사용되는 것을 기억합니다 ... –

관련 문제