2010-01-12 9 views

답변

27

구현에 따라 다릅니다. 일반적으로 매번 호출되지만, 컴파일러가 word이 변경되지 않으며 그 strlen이 순수한 함수 (부작용 없음)라는 것을 알게되면 호출을 들어 올릴 수 있습니다.

참조 : http://underhanded.xcott.com/?page_id=15이 잘 알려진 예제가 악용되었습니다. :-)

+0

이것은 올바른 대답입니다 ... 실제로 컴파일러가 얼마나 영리한가에 달려 있습니다. – Noldorin

+0

제공된 예제에서 이것은 'char *'에서 수행되었는데 이는 포인터 나 지적 된 데이터가 일정하지 않음을 의미합니다. gcc가 실제로이 작업을 수행하고 있습니까? 그것은 엄청나게 위험한 것 같습니다. –

+0

@PP :'word'가 루프 안의 다른 곳으로 전달되지 않았거나 ('char const *'를 취한 함수에만 전달됨), 여러분의 코드는 단일 스레드로 추정되며 별칭이 필요 없다고 가정합니다 함수가 단항이거나 포인터가 '제한됨'으로 선언 되었기 때문에). 이 경우 데이터가 변경되지 않는다는 것이 꽤 안전한 가정이라고 말할 수 있습니다. –

8

는 루프의 모든 반복에 대해 평가됩니다 (편집 : 필요한 경우).

Tatu와 마찬가지로 word의 길이가 변경되지 않으면 for 루프 앞에 strlen 호출을 수행 할 수 있습니다. 그러나 Chris가 말했듯이, 컴파일러는 word이 변경 될 수 없다는 것을 깨닫기에 충분할 수 있으며 중복 호출 자체를 제거 할 수 있습니다.

그러나 word이 루프 중에 길이가 변경 될 수 있다면 물론 루프 상태로 strlen 호출을 유지해야합니다.

+1

사실, 대부분의 컴파일러는'word'가 루프 본문 내에서 변경되지 않거나'volatile'으로 선언되는 한이를 최적화해야합니다. 언제나처럼, 당신은 무슨 일이 일어나는가를보기 위해 (dis-) 어셈블리를 점검 할 수 있습니다 ... – Christoph

+0

Bah, 이것은 완전한 대답에서 멀리입니다. 컴파일러가 반쯤 괜찮은 경우, 실제로 호출을 최적화해야하므로 한 번만 평가됩니다. – Noldorin

+0

사실, 컴파일러는 매번 호출을 최적화하고 회피하기에 충분히 똑똑 할 수 있습니다. –

0

strlen은 제공된 문자열의 길이를 확인합니다. 즉, 길이가 10 인 경우를 의미합니다. 내가 10 미만인 경우 반복이 계속됩니다.

그리고이 경우. 10 번.

Read more about loops

+0

-1 왜냐하면 문자열이 루프 내에서 수정 될 수 있고 따라서'strlen'은 무한 수 호출 될 수 있습니다 (컴파일러가'strlen()'의 결과를 캐싱하지 않는다고 가정 할 때). –

+0

또한이 예에서 'i'도 수정되지 않았 음을 보장하지 않았습니다. –

+0

그것은 다운 투표하는 어리석은 이유입니다. 그가 끈을 함부로 변경하지 않는다고 가정합니다. 첫 번째 모습에서 어떻게 보이는지, 그리고 루프가 어떻게 작동하는지에 대한 매우 기본적인 설명이었습니다. –

6

그 strlen 함수가 한 번만 호출되도록 같은 ...

for (int i = 0, n = strlen(word); i < n; ++i) { /* do stuff */ } 

이 ... (성능을 향상시키기 위해) 코드 가끔 ​​있습니다.

0

각 반복마다 호출됩니다. 다음 코드는 strlen 함수를 한 번만 호출합니다.

for (i = 0, j = strlen(word); i < j i++) 
{ /* do stuff */ } 
1

strlen(word) 실행되는 횟수에 따라 결정 word가 (데이터가 일정) 상수로 선언

  1. 경우
  2. 또는 컴파일러 word 변경되지 않은 것을 검출 할 수있다.

다음 예 보자이 예에서

char word[256] = "Grow"; 

for (i = 0; i < strlen(word); ++i) 
{ 
    strcat(word, "*"); 
} 

를 가변 word 루프 withing에 수정되어
가 0) "성장"- 길이 == 4
1) "성장 * "- 길이 == 5
2)"** "성장 -이 한 번만 호출되도록, 길이 == 6

그러나, 컴파일러는 strlen 호출을 인수 분해 할 경우, 바리 아 word가 상수로 선언 BLE :

void my_function(const char * word) 
{ 
    for (i = 0; i < strlen(word); ++i) 
    { 
    printf("%d) %s\n", i, word); 
    } 
    return; 
} 

함수는 변수 word 상수 데이터라고 선언 (실제로, 일정한 데이터-포인터). 따라서 길이는 변경되지 않으므로 컴파일러는 strlen 만 호출 할 수 있습니다.

의심 스러울 때 언제든지 직접 최적화를 수행 할 수 있습니다.이 경우에는 더 읽기 쉬운 코드가 표시 될 수 있습니다.

+3

'const'-qualified 포인터는 pointee가 특정 변수 (캐스팅하지 않음)를 통해 변경되지 않고 데이터 자체가 변경되지 않는다는 약속 일뿐입니다. – jamesdlin

관련 문제