c에 관한 문제요..

SoftOn의 이미지

학과 게시판에 올라와 있는데 아직 이해가 안되네요.. TT

아래의 k 값은 무엇이 될까요?

int i = 8;
int k = (i++) + (++i) + (i++) + (++i);

연산자 우선 순위(++, +, =)랑 + 연산자는 왼쪽 우선 순위까지는 알겠는데...
아무리 머리로는 답이 안나오네요..

컴파일 하지 말고 풀어 보세요.. -_ 그리고 컴파일해서 비교하면 전혀 생각지 않는 정답이..

GunSmoke의 이미지

두 sequence point 사이에서 저장될 새 값을 결정하는 목적 외의 목적으로 수정되는 대상체의 값을 참조하는 수식은 정의되지 않는 행동을 일으키는 잘못된 수식임을 밝히는 바입니다.

大逆戰

SoftOn의 이미지

문제가 있는건 알고 있습니다. 그리고 결과도 컴파일러에 dependent한것도 알고 있습니다.
단지 어떻게 값이 나오는지 궁금할 뿐입니다.. ^^;

저도 처음에는 무시했는데 visual c++와 gcc에서 컴파일 했을때 같은 값이 나오는 것을 봐서 뭔가 rule이 있는 것 같은데 전혀 모르겠습니다. --:

kyk0101의 이미지

예상한 결과는 40이었으나..

나온결과는 37이네요..

dev-c++ 4.9.9.1 에 들어있는 놈으로 컴팔했습니다.

I'm A.kin

theone3의 이미지

솔라리스에서 컴파일 했습니다.같은 머신에서 다른 컴파일러로 컴파일한 결과입니다.

CC

Quote:
i is 12
k is 42

gcc

Quote:
i is 9
k is 36

당신은 사랑받기 위해 태어난 사람.

Bini의 이미지

winxp + mingw32(gcc3.2.3)

i => 12
k => 37

지금은 거의 C를 사용하지 않지만 예전에 컴파일러마다 다른결과를 보인다고 들은것 같읍니다.
순전히 +연산자가 왼쪽우선순위로 하나하나 결합한다면
12 와 40이 나와야 되겠지요...

NeutralGray의 이미지

undefined behavior에 대해 왜 그런 결과가 나오는지를 따지는 것은 대체로 시간낭비입니다.

죠커의 이미지

예전에 devpia에 이 문제에 대해서 올려두고 gcc와 vc에서 다른 결과가 나오는 것에 대해서 간단히 설명하고 마지막으로 쓸모없는 이야기니 모두 잊어라고 글을 올렸습니다만 사람들은 잊지 않고 vc에서 왜 그렇게 나오느냐에만 관심을 가지더군요 :-)

잊는게 좋습니다. undefined에 목숨을 거는 것은 옵션 하나의 변경이나 버전 업 하나에도 바뀔 수 있는 문제를 암기하는 일입니다. (그 문제에 대해서 분석을 해봤으니 본인도 시간 낭비를 했습니다만..)

ㅡ,.ㅡ;;의 이미지

SoftOn wrote:
학과 게시판에 올라와 있는데 아직 이해가 안되네요.. TT

아래의 k 값은 무엇이 될까요?

int i = 8;
int k = (i++) + (++i) + (i++) + (++i);

연산자 우선 순위(++, +, =)랑 + 연산자는 왼쪽 우선 순위까지는 알겠는데...
아무리 머리로는 답이 안나오네요..

컴파일 하지 말고 풀어 보세요.. -_ 그리고 컴파일해서 비교하면 전혀 생각지 않는 정답이..

37이나오는 컴파일러라면..
(i++) + (++i) + (i++) + (++i);
첫째 둘째 셋째 넷째

연산자우선순위에따라 앞쪽 부터 계산되며..
먼저 앞쪽 두개(첫째둘째)중에서 괄호내부의 계산은 뒷쪽부터하게되어
결국 9+9 가되고..
그다음(셋째)은 18 + 9 가되고..
그다음은(넷째) 17 + 10 이되어..
37


----------------------------------------------------------------------------

GunSmoke의 이미지

SoftOn wrote:
문제가 있는건 알고 있습니다. 그리고 결과도 컴파일러에 dependent한것도 알고 있습니다.

unspecified behavior 와 implementation-defined behavior는 다른 개념입니다. 다음의 링크를 참고하십시오.

http://woong.org/board/?doc=bbs/gnuboard.php&bo_table=hclc&sselect=wr_subject%7Cwr_content&stext=undefined+implementation&soperator=1&page=4&wr_id=115

大逆戰

SoftOn의 이미지

그냥 신기해서 재미를 위해서 올렸는데.. 분류가 바뀌어있네요..
저도 처음에는 저 코드 자체에 문제가 있다는 생각은 하지 못하고
단순 계산으로 i=12, k=40이라고 생각했었습니다.
그런데 문제가 있기에 문제 제기를 한것입니다.. :oops:

덧. 답변을 달아 주신 분들 감사합니다.. :lol:

익명 사용자의 이미지

이 문제에 대해서는 왜 저런 동작이 나오는가보다는 왜 틀린 코드인가에 관심을 가지는게 훨씬 유익합니다. 보장해 주지 않는 동작에 대해서 왜 그렇게 동작하는지 연구하는 것보다는, 어디까지 보장해 주는가 아는 쪽이 더 중요합니다.

이에 대해서는 Sequence Point에 대해 구글이나 뉴스그룹 han.comp.lang.c 에서 검색하면 좋은 글들을 찾아볼 수 있습니다.

FlOw의 이미지

MinGW i:12 k:37
TurboC i:12 k:40
XP에서 돌렸습니다. 책에서는 컴파일러의 구현에 따라 달라지기 때문에
결과는 분명하지 않다고 적혀있네요 =3

-------------------- 절취선 --
행복하세요:)

죠커의 이미지

Gomdori wrote:
MinGW i:12 k:37
TurboC i:12 k:40
XP에서 돌렸습니다. 책에서는 컴파일러의 구현에 따라 달라지기 때문에
결과는 분명하지 않다고 적혀있네요 =3

구현에 따라 달라진다는(specified) 것은 잘못된 말입니다.

이전까지 논의 된 내용은 쓰면 안된다는 것(undefined)이죠 :-)

FlOw의 이미지

CN wrote:
Gomdori wrote:
MinGW i:12 k:37
TurboC i:12 k:40
XP에서 돌렸습니다. 책에서는 컴파일러의 구현에 따라 달라지기 때문에
결과는 분명하지 않다고 적혀있네요 =3

구현에 따라 달라진다는(specified) 것은 잘못된 말입니다.

이전까지 논의 된 내용은 쓰면 안된다는 것(undefined)이죠 :-)


:oops:
=3=3

-------------------- 절취선 --
행복하세요:)

익명 사용자의 이미지

여담이지만, 표준에서 사용되는 implementation-defined, unspecified, undefined는 일반적인 뜻으로 사용되는 용어가 아니라 상당히 기술적인 용어입니다.

implementation-defined behavior : unspecified behavior where each implementation documents how the choice is made

undefined behavior: behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

unspecified behavior: behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance

보통 C 언어 책에서는 이 세가지를 '컴파일러의 구현에 따라 달라진다'라는 한가지 표현으로 쓰기도 합니다. 하지만 약간씩 미묘한 차이가 있습니다.

undefined behavior에 의존하는 코드는 절대로 쓰지 말아야 합니다. 위에 CN님이 말씀하신 대로, 옵션 하나의 변경이나 버전 업 하나에도 바뀔 수 있는 문제이기 때문입니다. (좀 더 심하게는, 같은기종 같은컴파일러에서도 랜덤하게 다양한 결과를 보여주거나 혹은 컴퓨터를 날려버려도 할말이 없습니다) 오로지 허용되는 경우는 단 하나, 표준 이외의 방법(POSIX나 IEEE754 같은 별개의 표준이나 혹은 컴파일러 제작자가 제공하는 문서)으로 그 동작이 정확히 보장된 경우에 한해서 입니다.

댓글 달기

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