데굴데굴이
데굴이의 개발일지
데굴데굴이
전체 방문자
오늘
어제
  • 분류 전체보기
    • 프로그래밍
      • C,C++
      • C#
      • 백준(BOJ)
      • 알고리즘
      • HTML
      • WinAPI
      • ETC
    • 유니티
      • 쉐이더
    • 컴퓨터 구조
    • 일본어

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • BOJ
  • multable
  • 평가 순서
  • 10811
  • 정적 라이브러리
  • 동적 라이브러리 적용
  • C언어
  • 1158번
  • 25644번
  • c++
  • 25644
  • 알고리즘
  • C
  • 라이브러리
  • 라이브러리 적용
  • 동적 라이브러리
  • 컴파일
  • 동적 라이브러리 만들기
  • 백준
  • 1032번#
  • 전처리
  • msvc++
  • 최대 상승
  • 10811번
  • 시퀀스 포인트
  • Sequence Point
  • 바구니 뒤집기
  • 1343번
  • 재귀함수가 뭔가요?
  • 정적 라이브러리 만들기

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
데굴데굴이

데굴이의 개발일지

프로그래밍/C,C++

C 평가 순서 [unspecified, undefined, Sequence Point]

2022. 12. 30. 02:51
반응형

문제

이 코드를 실행했을때 콘솔창에는 어떤 결과가 나올까요 ? 

  1. ( 1 , 2 )
  2. ( 2 , 1 )
  3. ( 2 , 2 )
  4. ( 1 , 1 )

정답은 바로 ' 모른다 ' 입니다.

 

 

평가 순서

왜 그럴까요? 이 이유를 알려면 C언어의 평가 순서에 대해 알아야 이해할수가 있습니다.

C언어의 평가순서는 'unspecified' 이며 인자나 피연산자가 왼쪽부터 평가될지, 오른쪽부터 평가 될지 혹은 동시에 평가될지는 컴파일러마다 다르기 때문에 코드만 봐서는 결과를 예측할수가 없습니다.

 

그리고 이런 현상을 'undefine' 라고 부르는 것 입니다.

 

💡 Unspectified [ 표준에서 명시되지 않은 ]
: 표준에서 동작 방식을 정하지 않고, 컴파일러가 자신의 환경에 맞게 알아서 기능을 동작 시킨다는 의미.

💡 Undefine [ 표준에서 정의되지 않은 ]
: 표준에서 동작의 결과를 정하지 않기 때문에, 컴파일러마다 결과가 달라서 위험할 수 있음.

 

그럼 평가 순서는 어떨때 발생하는 것일까요.

 

첫번 째는 '함수에 인자가 여러 개일 경우.'

두번째는 '피연산자가 여러 개일 경우.'

 

이렇게 두가지가 있다고 볼수 있습니다. 

 

 

 

해결 방법

그럼 컴파일마다 결과가 다르다면 다른 프로그래머가 봤을때, 혹은 내가 다시 봤을때 이 코드의 결과를 눈으로 봤을때 판단하기 어려워지고 그것은 가독성에 안좋은 영향이 끼치며, 개발자가 생각했던 결과와 다르게 나와 오류가 생길수 있습니다.

 

이 오류는 컴파일, 링크 오류같은 빌드에서 나오는 오류가 아니기 때문에 컴파일러에선 오류를 안내기 때문에 찾기도 어려울 수도 있습니다. ( 똑똑한 컴파일러는 찾아줄수도 있습니다. )

 

그럼 어떻게 해결해야 할까요 ?

  1. 한 구분에 하나의 변수를 여러번 바꾸지 않는다.
  2. 한 구분에 여러번 함수를 호출하지 않는다.
  3. '시퀀스 포인트(Sequence Point)' 문자를 사용한다.

위와 같은 방법이 있습니다.

 

 

시퀀스 포인트(Sequence Point)

평가 순서를 강제하는 문자를 의미 합니다.

또는 모든 연산에 의한 결과가 완료되는 지점으로도 의미를 합니다.

 

대표적으로

  • ; ( 세미콜론)
  • ||, && ( 논리 연산자 )
  • ? : ( 삼항 연산자 )

세가지를 볼수 있습니다.

 

시퀀스 포인트는 컴파일러가 구문을 읽다가 시퀀스 포인트를 만나면 이전에 본 변수나 함수들을 다 평가해야 합니다.

 

만약  'a && b' 를 쓴다고 하면 앞에서부터 연산을 하여 a 부터 연산을 하는데  만약 앞에서 하나라도 false 일때 그 뒤에는 호출을 안하고 그대로 넘어가는 것 입니다. ( 이것을 'short circuit 평가' 라고 합니다. )

 

연산자 우선순위와 평가 순서

연산자 우선 순위는 평가 순서에 영향을 끼치지 않습니다.

왜냐하면, 연산하려면 값을 먼저 알아야 하기 때문에 항상 평가가 먼저 이루어 지기 때문입니다.

 

예를 들면, a() + b() * c() 를 계산한다고 하면 연산자로 계산을 할려면 '값'을 알아야하기 때문에 평가를 먼저 하여 

'5 + 7 + 9' 값을 먼저 정하고 그 후에서야 연산자의 우선순위로 계산이 되는 것 입니다.

 

 

마무리

우리가 코딩을 하면서 구문을 끝낸다는 의미로 세미콜론을 쓰였는데 이것의 정확한 용어가 시퀀스 포인터라고 하는것을 알게되었고, '&&', ' || ' 와 같은 논리연산자도 세미콜론과 같은 시퀀스 포인터라고 알게되었을때 꽤나 신기했던것 같습니다.

 

'정확한 결과' 가 아닌 '랜덤한 결과' 가 나온다는 것은 정확한 계산을 제일 중요시하는 컴퓨터에서는 절대로 있어서는 안될 일이기에 이런 것도 있다는 것을 알고 조심을 해야할것 같습니다.

 

이런 이유로 오류도 나온다는 것을 알게되었으니 나중에 오류를 찾을때 좀더 쉽게 찾을수 있을거라 생각합니다.

 

 

 

반응형

'프로그래밍 > C,C++' 카테고리의 다른 글

[C++]람다 표현식(Lambda Expression) 정리  (0) 2024.02.04
C++ 동적 라이브러리 만들기  (1) 2023.01.03
C++ 정적 라이브러리 만들기  (0) 2023.01.03
C++ 입력 버퍼 초기화 [ cin.ignore() ]  (0) 2022.12.28
    '프로그래밍/C,C++' 카테고리의 다른 글
    • [C++]람다 표현식(Lambda Expression) 정리
    • C++ 동적 라이브러리 만들기
    • C++ 정적 라이브러리 만들기
    • C++ 입력 버퍼 초기화 [ cin.ignore() ]
    데굴데굴이
    데굴데굴이

    티스토리툴바