C의 함수 파라메터로 '함수'(함수 포인터가 아니라)가 선언된 경우

raymundo의 이미지

안녕하세요,

#include <stdio.h>
 
// typedef void ptr(int);
 
void foo(int n) {
    printf("foo:%d\n", n);
}
 
void bar(int n) {
    printf("bar:%d\n", n);
}
 
void sub(void p(int), int n) {    // 여기 있는 p가
    p(n);       // 실행도 잘 되고
    p = bar;    // 할당도 잘 됨
    p(n);
}
 
int main(void)
{
    void pm(int);
//    pm = foo;       // 이건 "invalid lvalue in assignment" error
    sub(foo, 123);
}

sub()함수의 첫번째 인자가... 원래는 void (*p)(int) 라고 했을 텐데,
이걸 그냥 저렇게 마치 함수 원형 선언하듯 적어 봤습니다. 그런데 컴파일 및 실행에 전혀 문제가
없더군요.

반면에 main 함수 내에서 똑같은 타입(?)으로 선언한 pm의 경우는, "invalid lvalue in assignment" 에러가 납니다.
(혹시나 해서 sub 함수 내에서 동일하게 해봐도 동일한 에러가 납니다)

제가 추측하건데,
함수의 매개변수 리스트에 쓰였을 때에 한해서 int arr[] 이런 매개변수가 int *arr 이렇게 포인터로 처리되는 것처럼
void p(int) 이런 매개변수 역시 void (*p)(int) 이렇게 포인터로 자동으로 바뀌어 처리되는 게 아닌가...인데요,

이걸 구글링하려 해도 일반적인 함수 포인터를 파라메터로 쓰는 얘기만 검색되고... 정확히 언급한 것을 못 찾겠습니다.

가르침 부탁드리겠습니다, 감사합니다.

freestyle의 이미지

6.5.2.2 Function calls
78) ... A parameter declared to have array or function type is converted to a parameter with a pointer type as described in 6.9.1.

6.9.1 Function definitions
14. EXAMPLE 2.
void g(int (*funcp)(void))
...
or, equivalently,
...
void g(int func(void))

----------------------------------------------------------------------------------------
Don't Feed the Trolls!
----------------------------------------------------------------------------------------

raymundo의 이미지

감사합니다! 배열 또는 함수라고 나왔는데 배열은 어느 책이건 언급되는데 함수는 집에 있는 책들 다 훑어도 안 보이더라고요 ^^;

좋은 하루 되세요!

M.W.Park의 이미지

syntactic sugar의 일종으로 보입니다.
기본적으로 c/c++에서 함수는 first class object가 아니므로 파라미터로 전달될 수는 없다고 보는 것이 맞겠습니다.

-----
오늘 의 취미는 끝없는, 끝없는 인내다. 1973 法頂

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.