C의 함수 내에서 function prototype 선언시 문제점

소리의 이미지

C 표준(c89/c99)이 함수 내 함수(nested function)는 허용하지 않지만 prototype의 선언은 허용한다고 합니다.

즉 다음과 같은 코드가 가능할 거라고 생각합니다.

#include <stdio.h>

int main(void)
{
        /* function prototype declaration inside function */
        /*int foo(int x);*/       /*(1)*/
        static int foo(int x);    /*(2)*/

        printf("%d\n", foo(100));

        return 0;
}

/*int foo(int x)*/       /*(1)*/
static int foo(int x)    /*(2)*/
{
        return x;
}

이 코드에서 (1)은 기본값인 external linkage를 갖는 함수의 형태이고, (2)는 static 키워드를 사용하여 internal linkage를 갖는 함수의 형태입니다.

컴파일을 해 보았는데, (1)의 경우는 예상대로 아무런 에러나 경고 없이 잘 컴파일 되었지만 (2)의 경우엔 gcc가 이런 다음 경고 메시지를 출력하더군요.

Quote:
$ gcc -pedantic -Wall -std=c99 code.c
four.c: In function `main':
four.c:7: warning: invalid storage class for function `foo'

물론 실제로 함수 내에서 prototype 선언을 할 일은 없겠지만, C의 내부 기능들을 샅샅이 파헤치던 중이라서요.

표준이 원래 함수 내부에서 하는 prototype의 경우는 extern(실제론 아무것도 적지 않는 디폴트)만 허용하는 것인지, 그리고 그것보다 static 함수의 경우 어떤 문제가 있어서 이런 현상이 생기는 것인지 궁급합니다.

GCC의 버그같아 보이진 않고, 분명 무언가 이유가 있을 것 같은데... :roll:

feelpassion의 이미지

제 머신에선 아무 이상없이 컴파일이 되는데요....^^;;;
레뎃9.0입니다.
기냥 gcc -o test test.c라고 했는데

남으로 창을 내겠소.
밭이 한참갈이 괭이로 파고 호미론 김을 메지요.
구름이 꼬인다 갈리있소. 새들의 노래는 공으로 들으랴오.
강냉이가 익거든 와자셔도 좋소.
왜 사냐건 웃지요.

doldori의 이미지

기억 부류 지정자(storage-class specifier)는 typedef, extern, static, auto,
register의 5개가 있는데 C99 표준에 의하면

Quote:
6.7.1/5
The declaration of an identifier for a function that has block scope shall
have no explicit storage-class specifier other than extern.

즉 block scope 내에서 static 함수를 선언하는 방법은 없는 것이죠. gcc에서 경고로
그치는 것은 컴파일러의 확장 기능인 것 같습니다.
왜 이런 제한을 두는지는 저도 잘 모르겠군요.
전웅의 이미지

wwl wrote:
표준이 원래 함수 내부에서 하는 prototype의 경우는 extern(실제론 아무것도 적지 않는 디폴트)만 허용하지 않는 것인지, 그리고 그것보다 static 함수의 경우 어떤 문제가 있어서 이런 현상이 생기는 것인지 궁급합니다.

아무 것도 적지않은 암시적인 extern 은 물론, 명시적인 extern 도
허락됩니다.

doldori wrote:
기억 부류 지정자(storage-class specifier)는 typedef, extern, static, auto,
register의 5개가 있는데 C99 표준에 의하면
Quote:
6.7.1/5
The declaration of an identifier for a function that has block scope shall
have no explicit storage-class specifier other than extern.

즉 block scope 내에서 static 함수를 선언하는 방법은 없는 것이죠. gcc에서 경고로
그치는 것은 컴파일러의 확장 기능인 것 같습니다.
왜 이런 제한을 두는지는 저도 잘 모르겠군요.

근본적인 원인은 static 이라는 storage class specifier 가 C 언어에서
중의적으로 사용되기 때문입니다.

책에서도 (더 친절하게) 다뤘던 내용으로 기억합니다만, block 외부에서는
명칭의 linkage 를 internal 로 명시하기 위한 역할을 하며, 내부에서는
대상체의 storage duration 을 static 으로 명시하기 위한 역할을 합니다.
따라서 함수명의 linkage 명시를 위한 목적으로 block 내에서 쓰일 수 없는
것입니다.

결국, 함수 안에서의 함수 선언은 기본적으로 extern 만을 갖게 되고, 이
상황에서 무조건 external linkage 로 결정되는 것이 아니라 해당 위치에서
보이는 선언의 linkage 를 우선적으로 따라가게 됩니다. 결국 internal
linkage 를 명시하는 함수 선언이 scope 내에 보인다면 함수 내에서
이루어진 함수 선언도 internal linkage 선언이 될 수 있습니다. internal
linkage 의 특성상 함수 내부에서만 보이는 internal linkage 선언이
불필요하다는 것, 혹은 가능하더라도 바람직하지 않다는 것은 충분히
동의하시리라 믿습니다.

이제 다음 질문은 "그렇다면 extern/static 과 동일하게 storage class
specifier 로 정의되어 있는 typedef 는 허락되느냐, 아니냐" 가 되는
것인가요? ;-)

p.s. 울고 싶을 정도로 바쁘군요. T.T

--
Jun, Woong (woong at gmail.com)
http://www.woong.org

doldori의 이미지

그렇군요. 설명하신 이유에 대해서는 동의합니다.

전웅 wrote:

이제 다음 질문은 "그렇다면 extern/static 과 동일하게 storage class
specifier 로 정의되어 있는 typedef 는 허락되느냐, 아니냐" 가 되는
것인가요? ;-)

당연히 허락되지 않는다고 생각하고 있었는데 이 말씀의 의도는 무엇인지요?
함수 포인터형이 아닌 함수에 대한 typedef라는 것이 의미가 있나요? :shock:

ps. 개정판 출판도 바쁘신 이유 중의 하나겠지요? 무척 기대하고 있습니다. :)

소리의 이미지

두 분의 답변 대단히 감사합니다.

전웅 wrote:
책에서도 (더 친절하게) 다뤘던 내용으로 기억합니다만, block 외부에서는
명칭의 linkage 를 internal 로 명시하기 위한 역할을 하며, 내부에서는
대상체의 storage duration 을 static 으로 명시하기 위한 역할을 합니다.
따라서 함수명의 linkage 명시를 위한 목적으로 block 내에서 쓰일 수 없는
것입니다.

설명해주셔서 감사합니다. 잘 알았습니다.

그런데 솔직히 여기에 대해서도 한 가지 의문이 생깁니다.

제가 보기에, static의 의미를 전역에서 쓰일 때와 지역에서 쓰일 때를 구분했다면, 어차피 함수는 전역 함수만 존재하니, 지역에서 쓰일 때도 변수의 선언시 쓰이는 static과 함수의 선언시 쓰이는 static의 의미를 구분해도 될 것 같습니다.

일단 자문자답해본다면, C에서 함수의 선언과 변수의 선언을 동등하게 취급하겠다는 것 같은데.
...음, 이것도 아닌 것 같군요. 그렇다면 extern을 적어주지 않은 함수내 함수의 선언을 변수와 같이 auto로 간주해야 할 텐데, 함수내 함수의 선언은 기억부류가 프로그래머에 의해 지정되지 않았을 경우 변수와 달리 extern으로 간주하는 걸 볼 수 있었습니다.

저로선 풀어지지 않는군요... 답변 부탁드립니다. T_T

전웅 wrote:
wwl wrote:
표준이 원래 함수 내부에서 하는 prototype의 경우는 extern(실제론 아무것도 적지 않는 디폴트)만 허용하지 않는 것인지, 그리고 그것보다 static 함수의 경우 어떤 문제가 있어서 이런 현상이 생기는 것인지 궁급합니다.

아무 것도 적지않은 암시적인 extern 은 물론, 명시적인 extern 도
허락됩니다.


옙. ('허용하지 않는 것'이 아니라 '허용하는 것'을 의도한 거였는데 저렇게 적어 버렸군요. 수정했습니다. :D)

전웅 wrote:
결국, 함수 안에서의 함수 선언은 기본적으로 extern 만을 갖게 되고, 이
상황에서 무조건 external linkage 로 결정되는 것이 아니라 해당 위치에서
보이는 선언의 linkage 를 우선적으로 따라가게 됩니다. 결국 internal
linkage 를 명시하는 함수 선언이 scope 내에 보인다면 함수 내에서
이루어진 함수 선언도 internal linkage 선언이 될 수 있습니다. internal
linkage 의 특성상 함수 내부에서만 보이는 internal linkage 선언이
불필요하다는 것, 혹은 가능하더라도 바람직하지 않다는 것은 충분히
동의하시리라 믿습니다.

친절하게 설명해 주셨는데... 솔직히 잘 모르겠습니다.
함수 내부에서만 보이는 internal linkage의 불필요성과 바람직하지 못함에 대해선 동의합니다.
그런데 실제로 위에 제가 예제로 올린 코드의 (2)와 같은 경우, 해당 코드에서 함수내 함수선언의 static을 빼 주었을 때 전웅님의 말씀대로라면 잔말없이 internal linkage 선언을 따라야 할 텐데, static을 빼 주었기 때문에 extern으로 인식하여 실제적으로 유효한 선언인 함수 구현부의 static int foo(int x);과 충돌하고 경고 메시지를 출력함을 볼 수 있습니다. 그리고 말씀하신 내용과 완전 일치하게 만들기 위해 '해당 위치에 보이는 선언'을 main함수 앞 전역에 만들어 주면, 함수내 함수의 선언에 대해 'foo' defined but not used라는 경고을 주는 것으로 보아 이 경우 선언을 아예 다른 종류의 함수 정의로 이해하는 것 같습니다.

너무 복잡하군요. 제 이해력이 부족해서 그런 것이겠지만 솔직히 표준 협의회(?)에, 어차피 nested function을 허용하지 않는다면, 이렇게 복잡한 문제가 많은 inside-function function declaration을 왜 허용한 거냐고 묻고 싶어 지네요. :cry:

소리의 이미지

feelpassion wrote:
제 머신에선 아무 이상없이 컴파일이 되는데요....^^;;;
레뎃9.0입니다.
기냥 gcc -o test test.c라고 했는데

gcc에서 -std 옵션을 따로 지정해주지 않으면 GNU89 표준을 따라 컴파일합니다. (GCC 3.4.3의 맨페이지 기준 ^^) 그래서 C89 표준에 따라 컴파일하시려면 -std=c89 옵션을, C99를 원하시면 -std=c99를 적어주셔야 합니다.

GCC의 경고 출력과 관련된 옵션들은 다음 링크를 참고하세요.
http://gcc.gnu.org/onlinedocs/gcc-3.4.3/gcc/Warning-Options.html

전웅의 이미지

doldori wrote:
그렇군요. 설명하신 이유에 대해서는 동의합니다.

전웅 wrote:

이제 다음 질문은 "그렇다면 extern/static 과 동일하게 storage class
specifier 로 정의되어 있는 typedef 는 허락되느냐, 아니냐" 가 되는
것인가요? ;-)

당연히 허락되지 않는다고 생각하고 있었는데 이 말씀의 의도는 무엇인지요?

쉽게 생각하는 것과 다르게 허락됩니다.

doldori wrote:
함수 포인터형이 아닌 함수에 대한 typedef라는 것이 의미가 있나요? :shock:

자주 사용되지는 않지만 금지되지는 않습니다. 예를 들면,

typedef int func(void);
func foo;                /* function declaration */
func *foo(func *ptr);    /* function (pointer to func) returning pointer to func
                            where func is a function (void) returning int */

와 같은 것들이 가능합니다.

typedef int func(void);

와 같은 선언은 함수 내에서도 허락됩니다. 표준에서 extern 외에는 쓸 수
없다고 했는데, 같은 storage class specifier 인 typedef 가 허락되는
이유는 typedef 를 사용한 선언은 함수명 선언이 아니라, type name 의
정의이기 때문입니다. 이 부분 역시 표준의 말장난 중 하나입니다. :-(

wwl wrote:
전웅 wrote:
책에서도 (더 친절하게) 다뤘던 내용으로 기억합니다만, block 외부에서는
명칭의 linkage 를 internal 로 명시하기 위한 역할을 하며, 내부에서는
대상체의 storage duration 을 static 으로 명시하기 위한 역할을 합니다.
따라서 함수명의 linkage 명시를 위한 목적으로 block 내에서 쓰일 수 없는
것입니다.

설명해주셔서 감사합니다. 잘 알았습니다.

그런데 솔직히 여기에 대해서도 한 가지 의문이 생깁니다.

제가 보기에, static의 의미를 전역에서 쓰일 때와 지역에서 쓰일 때를 구분했다면, 어차피 함수는 전역 함수만 존재하니, 지역에서 쓰일 때도 변수의 선언시 쓰이는 static과 함수의 선언시 쓰이는 static의 의미를 구분해도 될 것 같습니다.

예, 충분히 가능합니다. 즉 이 문제는 언어 설계의 관점에서 이루어진
선택입니다. 예를 들어, 말씀하신 것처럼 함수 내부에서 대상체 선언에
적용된 static 은 storage duration 을 위한 것으로, 함수명 선언에 적용된
staitc 은 internal linkage 명시를 위한 것으로 해석되도록 정의할 수도
있습니다. 하지만, static 의 중의성을 통한 혼란을 최소화하겠다는 취지로
block 외에서는 linkage 명시를 위한 것/block 내에서는 static storage
duration 명시를 위한 것으로 원칙을 정한 세운 것입니다. hclc 에 static
의 중의성과 관련해 매우 오래 전에 포스팅했던 글이 있습니다.

wwl wrote:
전웅 wrote:
결국, 함수 안에서의 함수 선언은 기본적으로 extern 만을 갖게 되고, 이
상황에서 무조건 external linkage 로 결정되는 것이 아니라 해당 위치에서
보이는 선언의 linkage 를 우선적으로 따라가게 됩니다. 결국 internal
linkage 를 명시하는 함수 선언이 scope 내에 보인다면 함수 내에서
이루어진 함수 선언도 internal linkage 선언이 될 수 있습니다. internal
linkage 의 특성상 함수 내부에서만 보이는 internal linkage 선언이
불필요하다는 것, 혹은 가능하더라도 바람직하지 않다는 것은 충분히
동의하시리라 믿습니다.

친절하게 설명해 주셨는데... 솔직히 잘 모르겠습니다.
함수 내부에서만 보이는 internal linkage의 불필요성과 바람직하지 못함에 대해선 동의합니다.
그런데 실제로 위에 제가 예제로 올린 코드의 (2)와 같은 경우, 해당 코드에서 함수내 함수선언의 static을 빼 주었을 때 전웅님의 말씀대로라면 잔말없이 internal linkage 선언을 따라야 할 텐데, static을 빼 주었기 때문에 extern으로 인식하여 실제적으로 유효한 선언인 함수 구현부의 static int foo(int x);과 충돌하고 경고 메시지를 출력함을 볼 수 있습니다.

(2) 에서 처럼 static 을 빼주었을 때 해당 함수의 다른 선언이 scope 내에
존재하지 않기에 함수 내에서 static 없이 선언되었을 때는 external
linkage 로 간주됩니다. 그러다가 아래 함수 정의를 만나 internal linkage
임을 확인하고 충돌이 발생하는 것입니다.

wwl wrote:
그리고 말씀하신 내용과 완전 일치하게 만들기 위해 '해당 위치에 보이는 선언'을 main함수 앞 전역에 만들어 주면, 함수내 함수의 선언에 대해 'foo' defined but not used라는 경고을 주는 것으로 보아 이 경우 선언을 아예 다른 종류의 함수 정의로 이해하는 것 같습니다.

그렇지 않습니다. 실제로 프로그램에서 foo() 라는 함수가 정의되었지만
사용되지 않았기 때문에 알려주는 informative 성격의 경고로 볼 수
있습니다. 다음 프로그램은 같은 옵션에서 해당 경고를 받지 않습니다.

#include <stdio.h>

static void foo(void)
{
    puts("foo");
}

int main(void)
{
    void foo(void);

    foo();    /* use of foo() */

    return 0;
}

wwl wrote:
너무 복잡하군요. 제 이해력이 부족해서 그런 것이겠지만 솔직히 표준 협의회(?)에, 어차피 nested function을 허용하지 않는다면, 이렇게 복잡한 문제가 많은 inside-function function declaration을 왜 허용한 거냐고 묻고 싶어 지네요. :cry:

C 언어에서 문제 많고 복잡한 거 다 빼고나면 C 표준은 겉표지와 마지막
표지만 남지 않을까요? ;-)

언어적으로 바람직하지 못하다고 하여 무조건 언어 표준에서 배제할 수
있는 것은 아닙니다. 함수를 사용하기 전에 선언하는 것이 지금처럼
엄격하게 느껴지지 않던 시절, 함수 안의 함수 선언이 갖는 scope 이 block
scope 가 아닌 file scope 가 되도록 해주는 implementation 이 적지
않았다는 점을 생각하면 함수 안의 함수 선언이 갖는 중요성이 과거에는
다를 수 있었다는 점을 어느 정도 받아들이실 수 있지 않을까 생각합니다.

wwl wrote:
그래서 C89 표준에 따라 컴파일하시려면 -std=c89 옵션을, C99를 원하시면 -std=c99를 적어주셔야 합니다.

참고로, gcc 는 아직 C99 를 완벽히 지원하지 못하며, C89 도 100%
conformance 를 만족하는 것은 아닙니다 - 결국, 언어 정의 판단의
기준으로 특정 컴파일러를 사용하는 것은 그리 믿을만하지 못합니다.

그럼...

p.s. 그나저나 이 답변을 준비하면서 제가 책에서 다룬 내용 중 일부에
오류가 있음을 찾아냈습니다. :-( 그런데, 정작 그 책 내용의 근본을
이룬 예전 게시물을 찾을 수가 없군요.

--
Jun, Woong (woong at gmail.com)
http://www.woong.org

doldori의 이미지

전웅 wrote:

doldori wrote:
함수 포인터형이 아닌 함수에 대한 typedef라는 것이 의미가 있나요? :shock:

자주 사용되지는 않지만 금지되지는 않습니다. 예를 들면,

typedef int func(void);
func foo;                /* function declaration */
func *foo(func *ptr);    /* function (pointer to func) returning pointer to func
                            where func is a function (void) returning int */

와 같은 것들이 가능합니다.

typedef int func(void);

와 같은 선언은 함수 내에서도 허락됩니다. 표준에서 extern 외에는 쓸 수
없다고 했는데, 같은 storage class specifier 인 typedef 가 허락되는
이유는 typedef 를 사용한 선언은 함수명 선언이 아니라, type name 의
정의이기 때문입니다. 이 부분 역시 표준의 말장난 중 하나입니다. :-(


후우... 마구 헷갈리다가 6.7.7, 6.9.1 등을 뒤져보고 나서야 겨우 알게 되었습니다.
함수와 함수 포인터가 서로 다른 것이었군요. 어찌 보면 당연한 것인데 지금까지
모르고 있었네요. 덕분에 오늘도 또 배웠습니다.
소리의 이미지

전웅 wrote:
참고로, gcc 는 아직 C99 를 완벽히 지원하지 못하며, C89 도 100%
conformance 를 만족하는 것은 아닙니다 - 결국, 언어 정의 판단의
기준으로 특정 컴파일러를 사용하는 것은 그리 믿을만하지 못합니다.

잘 알겠습니다.
역시 C에 대해 정확하게 알기 위해선 ISO문서를 이용하는 수밖에 없겠군요. ^^;

바쁘신데도 시간내어 답변해 주셔서 정말 감사합니다.
전웅님 덕분에 이번에도 많은 걸 배웠습니다. :D

pynoos의 이미지

http://forums1.itrc.hp.com/service/forums/questionanswer.do?admit=716493758+1103049914870+28353475&threadId=58598

같은 문제가 이미.. 그리고 그 답은..

Quote:
After doing some reading I found that ISO C99
standard makes a pretty clear point of it:

6.7.1 Storage-class specifiers
...
5 The declaration of an identifier for a function that has block scope shall have no explicit storage-class specifier other than extern.
...

Thanks anyway...

전웅의 이미지

pynoos wrote:
http://forums1.itrc.hp.com/service/forums/questionanswer.do?admit=716493758+1103049914870+28353475&threadId=58598

같은 문제가 이미.. 그리고 그 답은..

Quote:
After doing some reading I found that ISO C99
standard makes a pretty clear point of it:

6.7.1 Storage-class specifiers
...
5 The declaration of an identifier for a function that has block scope shall have no explicit storage-class specifier other than extern.
...

Thanks anyway...

아마도 이 쓰래드나 인용하신 쓰래드 중 하나를 읽지 않으신 것 같습니다.
OP의 질문은 "왜" 금지했느냐 였습니다. 흠... 확실히 인용하신 쓰래드에서
질문하신 분(한때 뉴스그룹에서 종종 보던 아이디군요)은 OP에 비해
호기심이 적은 것 같습니다. :-)

--
Jun, Woong (woong at gmail.com)
http://www.woong.org

pynoos의 이미지

아.. 그렇군요 :)
이런 실수를... 크..

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.