[C/C++] shift operator 사용 시 주의
2019. 7. 19. 03:00ㆍ프로그래밍/C/C++
728x90
728x90
서론
- 회사에서 pvs 정적분석 툴을 사용하는데 엔진 코드에 shift 연산자에 관한 검출 결과가 많았따.
- https://www.viva64.com/en/w/v610/
- 에러는 shift 연산자를 사용할 때 left, right 피연산자가 음수일 때, right 피연산자가 32를 넘어갈 때 등을 고려하고 있다.
예제
const signed long long test[4] = {
1024 << -1, (signed long long)1024 << -1,
-1 << 32, (signed long long)(-1) << 32
};
- 나는 엔진코드를 잘 몰라서 이런 소스를 거의 본적이 없지만 -1을 << shift 연산자를 통해 -2^n을 표현할 수 있는 것 같다.
- 이런 방식과 유사하게 여러 수식이나 계산을 하는 코드들이 pvs에 검출되었다.
right 피연산자가 -1인 경우
- 우선 -1만큼 shift하는 것은 미정의 동작으로 VS2015 기준 C++ 컴파일러는 0을 리턴한다.
- right 피연산자가 int num; 같이 선언되어 있다면 num이 음수가 될 가능성을 고려해야 한다.
[0] 0 const __int64
[1] 0 const __int64
- 해결은 right 피연산자에 음수가 될 가능성을 배재하는 방식으로 코드를 짠다.
right 피연산자가 32보가 커질 수 있는 경우
- "-1 << 32"에서 컴파일러가 -1을 어떤 타입으로 결정할지는 컴파일러마다 다르고 예상할 수 없다.
- VS2015 기준 C++ 컴파일러는 해당 정수를 int 타입으로 취급하고 있으며 이는 32비트 표현 한계를 가진다.
- right 피연산자가 32보다 큰 경우 shift 범위가 int 타입 표현 한계를 넘어버려 미정의 동작일 수 있다는 이야기.
[2] 0 const __int64
[3] -4294967296 const __int64
- 해결은 캐스팅을 통해 left 피연산자의 타입을 확실히 지정해준다.
- 32 이상이 문제라고 나오고 있지만 사실상 컴퓨터가 표현할 수 있는 범위를 넘는 right 피연산자가 존재하면 안되는 것이라 생각한다.
- 현재는 64비트가 제한 기준이지만 나중에 128, 256이 나오면? 그러므로 right 피연산자의 범위 체크 코드를 예쁘게 짜놔야 될 것이라 생각한다.
728x90
반응형
'프로그래밍 > C/C++' 카테고리의 다른 글
[C] 예전 스타일 함수 선언. K&R-Style Declarations (1) | 2019.07.23 |
---|---|
[VS] tab, space 보기 (0) | 2019.02.27 |
[Boost] 설치 (0) | 2016.03.19 |
[C++] for each 써보기 (2) | 2016.01.19 |
[C++, Json] jsoncpp 사용하기 (5) | 2016.01.06 |
[C/C++] 삼항 연산자 (4) | 2015.11.27 |
[C++11] 주요 기능들 (0) | 2015.09.07 |