이거 답이 뭘까요?

hsnks100의 이미지

조금 재밌는 코드.

#include <iostream>
using namespace std;
 
void f(int a, int b)
{
	cout << a << b;
}
int main()
{
	int i=1;
	f(i++, i);
	i = 1;
	f(i, i++);
 
	return 0;
}

과연 답이 뭘까요?? ㅋㅋㅋ

신기신기... 미리 말하자면 불법적인 문장은 아닌거 같네요.

흔히 나오는 ++ 장난은 아닌거 같고요.
"한 문장에 하나의 변수가 두번 이상 바뀌는 것." 에도 포함되지 않네요.

snowall의 이미지

11
11

아닌가요??

피할 수 있을때 즐겨라! http://melotopia.net/b

익명 사용자의 이미지

1 2
1 1

shint의 이미지

a, b 인자값에 먼저 i값이 넣어지고
i에 +1 된값이 넣어진후
함수가 호출 됩니다.

#include <iostream>
using namespace std;
 
void f(int a, int b)
{
	printf("%d %d\n", a, b);
}
int main()
{
	int i=1;
	printf("i = %d\n", i);
	f(i++, i);
	printf("i = %d\n", i);
	i = 1;
	printf("i = %d\n", i);
	f(i, i++);
	printf("i = %d\n", i);
	return 0;
}

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

jsk의 이미지

재미있는 문제네요.
(gcc version 4.6.1으로 컴파일 해서) 실험한 결과는 "1221" 입니다.

1211 혹은 1121 이라면 납득이갈 것 같은데, 1221는 납득이 안가네요.
아래 어셈블리 코드는 g++ --save-temps ...로 (최적화 옵션 없이) 컴파일 해서 얻은 코드의 일부 입니다.

movl	$1, 28(%esp)   (i = 1)
movl	28(%esp), %eax (eax = i)
addl	$1, 28(%esp)   (i += 1)
movl	28(%esp), %edx (edx = i)
movl	%edx, 4(%esp)  (b = edx)
movl	%eax, (%esp)   (a = eax)
call	_Z1fii
 
movl	$1, 28(%esp)   (i = 1)
movl	28(%esp), %eax (eax = i)
addl	$1, 28(%esp)   (i += 1)
movl	%eax, 4(%esp)  (b = eax)
movl	28(%esp), %eax (eax = i)
movl	%eax, (%esp)   (a = eax)
call	_Z1fii

익명 사용자의 이미지

http://c-faq.com/expr/evalorder1.html

$ gcc -Wall -o ordre-c ordre.c
ordre.c: In function ‘main’:
ordre.c:10:5: attention : operation on ‘i’ may be undefined [-Wsequence-point]
ordre.c:12:8: attention : operation on ‘i’ may be undefined [-Wsequence-point]
jsk의 이미지

위 사이트의 내용을 책으로 엮은 "C Programming FAQs: Frequently Asked Questions"라는 책도 있는 것 같네요.
또 위 사이트를 번역 하신 분도 있는 것 같습니다.

* www.cinsk.org/cfaqs/cfaqs-ko.pdf

oosap의 이미지

위의 c-faq 의 설명이 맞는 것 같습니다.
f(i++, i);
이렇게 코딩하는 것은 K&R C 에서나 C 표준에서나 정의되지 않는다는 것이죠?

저는 변수 i를 volatile 변수로도 해보고 프로세스가 CPU affinity 를 강제받도록 해보기도 했으나 정상적인 결과는 나오지 않더라구요... 캐시나 CPU 문제는 아닌 것 같습니다.

Thanks for being one of those who care for people and mankind.
I'd like to be one of those as well.

익명 사용자의 이미지

parameter의 ,은 수식에서 사용하는 ,와 달리 evaluation 순서가 정의되어 있지 않기 때문에 어느 쪽이 먼저 실행될 지 알 수 없습니다. 따라서 저런 코드는 사용해서는 안됩니다.

랜덤여신의 이미지

윗분들도 말씀하셨지만, 정의되지 않은 동작입니다. 따라서 '불법적인 문장' 맞습니다.

hsnks100의 이미지

evaluation 순서가 정의되어있지 않더라도 저 문장은 하나의 statement 라고 볼 수 있지 않나요?

후위 증감연산자라는게 하나의 문장이 실행되고 증가가 되지 않나요?

----------------------------------------------------
개인 블로그: https://kangssu.com

oosap의 이미지

var[i] = i++;
func(i,i++);

이런 것들은 불법이고

var[3] = i++;
func(x,i++);

이런 것들은 누구나 알고 있는 내용이듯이 합법이구요..
그런것 같아요...

그렇다면,

var[i] = i;
func(i,i);

는 합법일까요 불법일까요?

Thanks for being one of those who care for people and mankind.
I'd like to be one of those as well.

hsnks100의 이미지

var[i] = i;
func(i,i);

합법이겠죠? 파라메터 평가할 때 순서가 중요하지 않으니까요...

i 자체에서 캐스팅 연산자가 호출되서 그 자신이 바뀌지 않는 이상요.

---------------------------------------------------
글쓴이 입니다. 주제가 자게에 있기 거시기 해서 플밍 qna 로 옮겼습니ㄷ.

----------------------------------------------------
개인 블로그: https://kangssu.com

익명 사용자의 이미지

그 이유는 parameter 처리 과정에서 i의 값이 변하지 않기 때문입니다.
(여기에서 i가 multithread로 바뀔 수도 있다거나 i를 매크로 치환하여 바꿀 수 있다는 태클은 논점 이탈이므로 생각하지 않겠습니다)

oosap의 이미지

위 두분 말씀이 맞는 것 같습니다.

여기서 제가 배운 교훈은 컴파일시 -Wall 옵션으로 워닝을 항상 검사하자는 것입니다.
워닝메세지가 위에계신 분이 처음 링크를 걸어주시면서 보여주셨듯이 적절하게 나오는군요.
워닝메세지가 크리티컬한 의미를 가지는 것을 확인한 제게는 드문 사례인 것 같습니다.

그리고

var[i] = i;
func(i,i);

는 아무런 워닝이 발생하지 않았습니다.

100% 확인사살까지 한 느낌입니다.

제가 원래 글을 올린 건 아니지만, 답글 감사드립니다.

재밌는 쓰레드였습니다. ^^; 워닝을 가볍게 보지 말아야겠습니다.

Thanks for being one of those who care for people and mankind.
I'd like to be one of those as well.

익명 사용자의 이미지

그 다음에 처리되는 parameter 처리의 evaluation 순서가 정의되지 않는 것이 문제입니다.

function(a, b, c);에서 a, b, c의 처리 순서는 알 수 없습니다.
반면 (a, b, c); 라고 한다면 이것은 statement로서 a -> b -> c의 순서로 처리됩니다.
(->는 화살표 표시입니다. 포인터 레퍼런스 아님)

처리 순서를 알 수 없을 때 사용한 변수들 간에 의존성(dependency)이 있다면 결과를 예측할 수 없는 문제가 발생하게 됩니다.

댓글 달기

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