함수 이름 주위의 괄호는 무엇을 의미합니까?


214

내 프로젝트 소스 파일 중 하나 에서이 C 함수 정의를 찾았습니다.

int (foo) (int *bar)
{
    return foo (bar);
}

참고 : 옆에 별표가 없으므로 foo함수 포인터가 아닙니다. 아니면? 재귀 호출로 여기서 무슨 일이 일어나고 있습니까?


7
아니요, 함수 포인터가 아닙니다. 여전히 foo라는 일반 함수입니다.
Nemanja Boric

이것이 완전한 기능입니까?
asheeshr

2
이 기능이 유용한 컨텍스트에서 사용되었다는 증거가 있습니까?
moooeeeep 2011

1
... 기존 소스에서 컴파일되어 제거되었는지 확인하기 위해 방금 작성된 더미 함수처럼 보입니다. 최악의 스택 오버플로에서 무한 루프 (C 컴파일러가 꼬리 호출을 최적화하도록 허용되는지 확실하지 않음)이므로 그것을 제거합니다 (함수가 실제로하는 경우).
하이드

3
C 선언의 괄호는 언어를 모호하게하는 데 도움이됩니다. 빨리, 무엇 a(b);입니까? b유형의 변수로 선언 a? 또는 a인수 를 사용하여 함수 를 호출 b합니까? 차이점은 구문 론적이며의 선언 정보를 찾지 않고 구문 분석하는 방법을 알 수 없습니다 a. 즉, postfix 함수 호출 괄호 또는 선언자 주위의 선택적 괄호입니다.
Kaz

답변:


329

전 처리기 작업이 진행되지 않는 경우 foo의 서명은

int foo (int *bar)

함수 이름 주위에 불필요한 괄호를 넣는 사람들을 본 유일한 컨텍스트는 동일한 이름을 가진 함수와 함수 같은 매크로가 있고 프로그래머가 매크로 확장을 막고 싶을 때입니다.

이 연습은 처음에는 조금 이상해 보일 수 있지만 C 라이브러리는 동일한 매크로를 가진 일부 매크로와 함수를 제공 하여 선례를 설정 합니다 .

이러한 기능 / 매크로 쌍 중 하나는 isdigit()입니다. 라이브러리는 다음과 같이 정의 할 수 있습니다.

/* the macro */
#define isdigit(c) ...

/* the function */
int (isdigit)(int c) /* avoid the macro through the use of parentheses */
{
  return isdigit(c); /* use the macro */
}

귀하의 함수는 위와 거의 동일하게 보이므로 이것이 코드에서도 진행되고 있다고 생각합니다.


2
여기에서도 마찬가지입니다. 매크로를 찾지 못했습니다 ... 괄호 안에 매크로 확장이 발생하지 않는다는 것을 몰랐습니다. 지적 해 주셔서 감사합니다!
user1859094

13
@ user1859094 : 두 번째로, 이것은 거의 확실하게 코드에서 일어나는 일입니다. foo(bar)함수 내에서는 해당 매크로를 사용한다.
NPE

78
@ user1859094 매크로 확장은 괄호 안에 이루어 지지만 함수형 매크로의 확장은 다음 토큰이 왼쪽 괄호 (C99, 6.10.3§10) 인 경우에만 발생하므로 foo (int* bar)대체되지는 않지만 (foo) (int *bar)(다음 토큰) after foois ))
Virgile

4
그러한 함수는 어떻게 호출됩니까? 괄호로도 부르시겠습니까? 예를 들어, 다음과 같이 작동 (isdigit)(5)합니까?
gcochard

4
@ 그레그 : 맞아요. 바로 그게 바로 전화입니다.
NPE

37

본당은 선언을 바꾸지 않고 여전히라는 일반 함수를 정의합니다 foo.

그것들이 사용 된 이유는 foodefined 라는 함수형 매크로가 있기 때문에 거의 확실합니다 .

#define foo(x) ...

(foo)함수 선언에서 사용 하면이 매크로가 확장되지 않습니다. 따라서 일어날 수있는 일은 foo()함수와 같은 매크로에서 본문이 확장되어 함수 가 정의되고 있다는 것 foo입니다.


5
좋은 공제 (이 목적으로 괄호를 사용하는 것은 법으로 처벌되어야 함).
ugoren

3
@ugoren : 함수 이름 주위에 parens를 사용하는 것은 함수와 유사한 매크로의 매크로 확장을 막는 유일한 방법입니다. 때때로 그것은 필요한 도구입니다.
Michael Burr

7
@MichaelBurr에는 동일한 이름의 매크로와 기능이없는 옵션도 있습니다. 나는 당신이 항상 모든 것을 통제 할 수는 없다는 것을 알고 있지만,이 해결책에 도달하면 뭔가 잘못되었다고 말할 것입니다.
우고 렌

-3

괄호는 의미가 없습니다.
표시하는 코드는 무한 재귀입니다.

함수 포인터를 정의 할 때 가끔 의미있는 이상한 괄호가 나타납니다. 그러나 여기서는 그렇지 않습니다.


6
분명히 그렇지 않습니다. 괄호는 매크로 확장을 방지합니다. 허용 된 답변을 참조하십시오.
케빈

12
@ 케빈, 내 대답은 표시된 코드에 관한 것이며 정확합니다. 알려지지 않은 전 처리기 정의가 모든 것을 바꿀 수 있다고 가정하면 거의 모든 C 질문에서. 이 경우 전처리기를 고려한 답변이 실제로 더 나아지지만 내 생각이 잘못되지는 않습니다.
ugoren
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.