C 문법 어떤게 맞을까요

smilejoon의 이미지

#include

void func(int a, int b, int c);

void main()
{
int a=0;
func(a++, a++, a++);
}
void func(int a, int b, int c)
{
printf("%d %d %d", a,b,c);
}

누군가 물었습니다. 결과는 어떻게 되냐고

여러분들은 어떻게 생각하시나요??

컴파일은 비주얼 스튜디오 6.0 과 비주얼 스튜디오 2003, 그리고

gcc(버전 확인안함;;) 이렇게 세가지에서 했는데

비주얼 스튜디오 6.0에서는 0, 0, 0 이라고 출력되고

나머지는 2,1,0 이라고 출력이 됩니다.

제 생각은 둘다 말이 된다는 생각이;; 쿨럭;;

근데 컴파일러가 다르더라도 결과가 저렇게 달라져도 될런지

궁금해서 한번 올려봅니다.

다른 분들은 어떻게 생각하시는지...

haze11의 이미지

예전에 a++, ++a 에 대한 포스팅이 있었는데, 결과적으로 컴파일러에 따라 다르다고 한거 같네요.
프로그램은 명확하게 짜는 것이 좋죠. 예상 결과가 안나오면 프로그램 짠 사람 탓입니다. :)

jick의 이미지

세 값이 각각 0, 1, 2 중 아무 값이나 와도... 프로그래머가 불평 못합니다. 그러면 27가지 케이스가 있겠네요.

뭐, 혹시라도 1, 2, 3 같은 게 뜨면 "이건 컴파일러가 이상한 거 아냐?"라고 고개를 갸우뚱해 보겠습니다만...

제가 컴파일러 짜는 사람이라면 "이런 코드를 넣고 어떤 *결과*를 바라다니! 나랑 다툴래요?" 하겠습니다. -_-;;

netionics의 이미지

다른 언어에서 함수 인자 평가 순서가 정해진 경우가 많지만 (자바나 c#같은 경우)

c, c++에서는 함수 인자 평가 순서는 표준에서 정의하지 않습니다.

구현자(여기선 컴파일러)가 제멋대로 순서 정해도 됩니다.

제대로 된 프로그램은 어떤 순서로 넘어가도 원하는 결과가 나오도록 짜야 합니다.

참고로 c++에서 이와 관련해서 예외발생에 관련된 미묘한 문제가 있는데 effective c++ 항목 29에 나와있습니다.

:)

kalevala의 이미지

컴파일러의 차이에 대해서 인정을 하셔야 할 수 밖에 없습니다^^;

실제로 2,1,0의 결과값을 얻기 위해 a++,a++,a++로 굳이 해야할 필요가

없는만큼 원하시는 결과값을 얻도록 코드를 재구성하시는 수 밖에는 없답니다.

park7275의 이미지

파싱부분의 차이인듯합니다.

기본적으로 C는 postfix 룰을 따른다는 것으로 기억합니다.

뭐 물론 함수 call parameter 에 대해선..--;

제가 보기엔 두번째 결과인

2,1,0 이 더 명확한게 아닌가 싶네요.

물론.compiler의 차이는 맞는것 같습니다.

[KILL] 죽을각오로.........

[KILL] 죽을각오로.........

M.W.Park의 이미지

주기적으로 올라오는 질문이네요. ㅋ

K&R에 그런식으로 쓰지 말라고 나오는 부분이 있었던 것으로 기억합니다.
참고하세요.

그리고 개인적으로는 명확함이 담보되지 않은 축약은 죄악에 다름없다고 생각합니다.

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

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

익명 사용자의 이미지

Quote:
개인적으로는 명확함이 담보되지 않은 축약은 죄악에 다름없다고 생각합니다

이 한문장에 감동했습니다. ㅜㅜ

thyoo의 이미지

C99 정리

func(a++, a++, a++);

6.5-2
한 Sequence Point(매개변수 평가완료시까지)에서
Stored value의 Write Access는 한 번까지만
허용하고 이를 어길시에는 Undefined Behavior.

6.5.2.2-10,12
함수 매개 변수의 평가 순서는 Unspecified Behavior.

마지막으로
표준에서는 "스택"에 대해서 전혀 언급이 없지만
C에는 가변 매개 변수가 있어서
일반적으로 Argument List의 역순으로 스택에 넣습니다.
gcc는 그 순서 대로 평가하는 모양이고
vc는 6.5-2에 걸려서 평가하지 않고 놔두는 모양입니다.

참고
Undefined Behavior vs. Unspecified Behavior
http://www.devx.com/tips/Tip/12684
___________________________________
Less is More (Robert Browning)

___________________________________
Less is More (Robert Browning)

jick의 이미지

"그렇게 살지짜지 마라"라는 얘기로군요... :)

표준에서 말하는 undefined behavior는 백지수표죠. OS가 그 순간 프로세스를 날려버려도 불평할 수 없습니다.

oppor의 이미지

저렇게 안 짜는게 맞는 겁니다.

익명 사용자의 이미지

함수 매개의 평가 순서가 Unspecified Behavior인 데는 다 이유가 있습니다.

빈곤한 환경에서는, 좀 더 복잡한 매개변수를 먼저 평가하는 것이 도움이 될 때가 있습니다.

f(g(), 1, 2, 3, 4);

이런 함수가 있을 때 어느 매개변수를 가장 먼저 평가하는 것이 좋을까요?

오른쪽에서 왼쪽으로 평가를 하게 된다면, g()가 실행되기 전에 숫자 4개를 레지스터에서 지웠다가 나중에 다시 읽어들일 필요가 있습니다. 그러나 g()를 먼저 평가한다면 그런 낭비를 줄일 수 있습니다.

댓글 달기

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