2010-05-09 4 views
28

순수은 함수가 전역 메모리를 수정하지 않는다는 함수 속성입니다.
const은 함수가 전역 메모리를 읽거나 수정하지 않는다는 함수 특성입니다.다른 컴파일러의 순수/const 함수 특성

이 정보가 주어지면 컴파일러는 몇 가지 추가 최적화를 수행 할 수 있습니다. GCC에 대한

예 :

그 예에서
float sigmoid(float x) __attribute__ ((const)); 

float calculate(float x, unsigned int C) { 
    float sum = 0; 
    for(unsigned int i = 0; i < C; ++i) 
     sum += sigmoid(x); 
    return sum; 
} 

float sigmoid(float x) { return 1.0f/(1.0f - exp(-x)); } 

, 컴파일러 최적화 할 수있는 기능 계산에 :

float calculate(float x, unsigned int C) { 
    float sum = 0; 
    float temp = C ? sigmoid(x) : 0.0f; 
    for(unsigned int i = 0; i < C; ++i) 
     sum += temp; 
    return sum; 
} 

또는 컴파일러가 충분히 영리 (약 그렇게 엄격하지 않은 경우 수레) :

float calculate(float x, unsigned int C) { return C ? sigmoid(x) * C : 0.0f; } 

GCC, Clang, ICC, MSVC 또는 다른 컴파일러와 같은 다른 컴파일러의 경우 이러한 방식으로 사용합니까?

+1

gcc를 정기적으로 사용하지 않는 사용자의 경우 pure/const 속성에 대한 설명을 게시 할 수 있습니다. 일종의 최적화라면 컴파일러가보다 최적의 어셈블리를 생성하는 데 도움이되는 C 또는 C++ 코드의 예가 유용 할 것입니다. –

+0

필자는 컴파일러 작성자가 아니지만 동일한 번역 단위에서'sigmoid()'함수 정의가 컴파일러 *에서 * calculate() 전에 사용 가능하다면 그러한 속성은 불필요하다고 생각합니다. 그럼에도 불구하고이 속성은 함수 정의가 다른 번역 단위에있을 때 확실히 유용 할 수 있습니다. – Void

+0

예, GCC (및 다른 컴파일러)는이 경우에이 속성을 내부적으로 자동으로 추가합니다. 그런 다음 속성을 기반으로 추가 최적화 작업을 수행 할 수 있습니다 (예와 같이). 컴파일러가 그 시점에서 정의를 보지 못하거나 정의가 사용 가능하지 않거나 컴파일러가 컴파일러의 양을 줄이면 안전하다고 생각하는 경우 함수 호출. – Albert

답변

26

일반적으로 거의 모든 컴파일러가 GCC 속성을 지원하는 것으로 보입니다. MSVC는 지금까지는 그들을 지원하지 않는 (그리고 어떤 대안도없는) 유일한 컴파일러입니다.

+1

MSVC도 이러한 특성에 대한 지원을 추가 할 의도가 없습니다. https://connect.microsoft.com/VisualStudio/feedback/details/804288/msvc-add-const-and-pure-like-function-attributes. 그들은 응용 프로그램에는 의미가 있지만 라이브러리에는 적합하지 않다고 말합니다. – bcmpinc

+2

GNU C를 언어 또는 언어 확장 집합으로 생각하십시오. '#if __GNUC__> 4 ||를 사용하여 모든 컴파일러에서 특정 GNU C 기능의 가용성을 테스트 할 수 있습니다. ... '또는 이와 유사한 것으로 (https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html) 권장됩니다. Clang (및 다른 컴파일러)은 완전히 지원하는'__GNUC__' 및'__GNUC_MINOR__' 버전 만 광고합니다. 구현은 gcc와 다를 수 있습니다 (예 :clang의'__builtin_constant_p()'는 인라인 된 함수의 함수 인수에 const를 넣지 않지만) 코드는 컴파일 될 것입니다. –

+1

즉, clang 및 ICC는 gcc 6.0의 새로운 기능을 지원할 수 있지만 gcc6.0이 수행하는 모든 언어 확장을 지원하는 버전에서는 '__GNUC__'을 6으로 정의하고'__GNUC_MINOR__'을 0으로 정의합니다. –