2011-03-10 3 views
8

내가 그것을 정의하기 전에 내 .c 파일에 선언 정적 기능을 갖고 싶어 : 그러나함수 정의에서 정적 키워드가 함수 정의에 누락 될 수 있습니까?

//file a.c version 1 
static int foo(); 
... 
static int foo() 
{ 
... 
} 

를, 내가 함수 정의 밖으로 static 키워드를 남길 수 있습니다 보인다 내가 어떤 컴파일러 경고를 얻을 ... 예.

//file a.c version 2 
static int foo(); 
... 
int foo() 
{ 
... 
} 

정확하게이 두 형식이 정확히 같다고 가정합니다.
그렇다면 왜이 불일치가 허용되며 어떤 양식을 사용해야합니까?

+0

나는 그/그녀가 진짜 큰 프로그램을 작성하지, 운동을하고 있다고 생각한다. 내 생각에, 첫 번째 Google은 그 유형 질문 때문에 그것은 사소한 것입니다. –

+1

@fatai : Google에이 질문을하는 것은 상당히 어렵습니다. 그리고 여기서 언어 변호사는 표준에서 인용문을 제공 할 것입니다. –

+1

질문에 대답 해 주신 Erik과 AProgrammer에게 감사드립니다 !! 미래의 선언/정의에서 정적 키워드를 생략 할 수있는 것이 바람직한 이유는 무엇입니까? 이점이 추가되지 않으면 혼란 스럽습니다. – Arrakis

답변

7

예 7.1.1/6

이 가지고하지 않는 한 저장소 클래스 지정자없이 네임 스페이스 범위에 선언 된 이름은 외부 링크가 있습니다 이전 선언으로 인해 내부 연결이 이루어지지 않았고 const으로 선언되지 않은 경우.

정적 특성은 컴파일 유닛 가시성을 변경도 7.1.1/7

+0

정확히 내가 뭘 읽고 있었는지 :) C++ 0x FCD에서 7.1.1/6이 바뀌 었습니다 7.1.1/7 (관심있는 사람들에게)되었습니다. 표현은 동일합니다. –

+0

@Matthieu, 우리는 교차 게시했습니다 ... – AProgrammer

+0

어디에서 찾았습니까? :/ – sami1592

1

static -이 컨텍스트에서는 범위에만 영향을 미칩니다. 함수를 정적으로 선언하면 파일 범위가 고정됩니다. 따라서 다른 소스에서 함수에 액세스하여 동일한 지 쉽게 확인할 수 있습니다.

우리가 등 컴파일러 언어에 대한 논의

3

7.1.1/7 피하기 그런 식 : 동의하여야한다 주어진 개체에 대한 연속 선언에 의해 암시

연계를. 즉, 주어진 범위 내에서 동일한 선언을 선언하는 각 선언은 객체 이름이 이거나 함수 이름이 인 동일한 오버로드는 연결을 의미합니다.

7.1.1/6 : -

스토리지 클래스 지정자없이 네임 스페이스 범위 에서 선언 된 이름은 있다 (감사 스티브 대답은 명확하게하기 위해이 또한 필요하다) 외부 연결은 이전의 선언으로 인해 내부 연결이 이 아니며 제공된 경우 const가 선언되지 않았습니다. const 으로 선언되고 명시 적으로 extern으로 선언 된 개체 은 내부 연결을 가지고 있습니다.

네, 두 개는 동일합니다.

그러나 이것은 잘못되었습니다

int foo(); 

static int foo() { 
    return 0; 
} 
+1

.. 질문자의 경우에 동의하는 이유는 7.1.1/6입니다. "저장소 클래스 지정자가없는 네임 스페이스 범위에서 선언 된 이름은 이전 선언으로 인해 내부 연결이없는 경우 외부 연결을가집니다." 그들은 같은 이유로 당신의 모범에 동의하지 않습니다. –

+0

전에 삽입 된 것이 있었지만 n3225의 7 번째는 C++ 03의 6 번째입니다. – AProgrammer

0

의 예를 참조. 이렇게하면 다른 목적으로 다른 파일에서 같은 이름을 사용할 수 있습니다. 정적을 한 번만 사용해야합니다. 프로토 타입이 있다면 여기에서해야합니다.당신이 C++을 요구하는 경우

당신은 컴파일 단위에 대한 symbold 비공개 정적하지만 익명의 네임 스페이스를 사용하지 않아야합니다 :

namespace { 
    int foo(); 
} 

void bar() 
{ 
    foo(); 
} 
0

을 (!) 참고로, C++는 static에 우수한 대안을 제공합니다. 또한

namespace 
{ 
    void f() 
    { 
    } 
} 

참조, 이름없는 네임 스페이스 여기

예를 사용할 수 있습니다이 :

Superiority of unnamed namespace over static?
Why an unnamed namespace is a "superior" alternative to static?

+0

필자는 기능상으로 우월함을 찾지 못했다. 그것은 더 많은 선언 (클래스/typedef)을 허용하므로, 함수와 상수에 대해서도 그것을 사용하면 통일 구문을 만들고 (키워드의 과부하를 제거 할 수 있습니다),'static'은 더 간결합니다. –

+0

물론 * namespace *와 * static 둘 다 사용할 수 있습니다. – Lundin

+0

이 컨텍스트의'static' 키워드는 일부 버전의 C++ 0x 초안에서 사용되지 않는 것으로 선언되었습니다. 그 결정은 취소되었고 그것은 폐기되었습니다. 특히 함수의 경우 일부 컴파일러는 이름이없는 네임 스페이스를 사용할 때보 다 정적 인 함수를 선언 할 때 더 나은 진단 기능을 제공합니다. 사실, 일부 컴파일러에서'static' 키워드는 컴파일러가 이름없는 네임 스페이스에서 같은 함수가 선언 될 때 취하지 않는 특정 자유 함수와 관련하여 취하는 결정 (최적화)에 영향을줍니다. –

관련 문제