3

우리는 리눅스 커널 안에 코드를 작성하고 있기 때문에 리눅스 커널 코드에서 작동하는 PC-Lint/Flexelint를 얻을 수 없었습니다. 너무 많은 내장 기호 등. 그러나 그것은 부작용입니다.컴파일러 경고를 사용하여 상수 1 왼쪽 시프트 오버플로 잡기?

우리는 gcc로 시작하는 컴파일러가 몇 가지 있지만 다른 것들도 있습니다. 그들의 경고 옵션은 시간이 지남에 따라 점점 강해지고 있으며, 정적 분석 도구 역시 강력합니다.

내가 알고 싶은 것은 다음과 같습니다. 그렇습니다. "no magic numbers"와 같은 코드 리뷰에서 쉽게 잡을 수있는 몇 가지 사항을 위반하고 "비트 시프트에주의하십시오."하지만 코드의 해당 부분을 살펴보아야 만합니다. 어쨌든, 여기있다 :

unsigned long long foo; 
unsigned long bar; 

[... lots of other code ...] 

foo = ~(foo + (1<<bar)); 

또한 업데이트] 문제 설명 -도 16로 제한 바, 여전히 문제. 명확히하자면, 문제는 암시 적 int 유형의 상수로, 계획되지 않은 경우 복잡한 계산식이 모든 계산이 동일한 크기와 부호로 수행된다는 규칙을 위반하게 만듭니다.

문제점 : '1'은 길지 않지만 작은 값 상수는 기본값이 int입니다. 그러므로 막대의 실제 값이 16을 초과하지 않더라도 여전히 (1<<bar) 표현이 오버플로되어 전체 계산이 망가질 수 있습니다.

아마도 올바른 해결책으로 대신 1ULL을 작성하십시오.

이 (수정 된) 문제점을 지적하는 잘 알려진 컴파일러 및 컴파일러 경고 플래그가 있습니까?

+0

막대의 길이가 너무 크면 이동이 정의되지 않습니다 (제 생각에는 다소 불량합니다). 당신은 변수를 두 번째 피연산자에 대한 int로 이동 경고에 대한 컴파일러를 요구하는 것 같습니다. 그러나 문제는 '1'이 길지 않다는 것입니다. 오랫동안 변수 이동에 대해 경고하고 싶지 않습니까? 필자는 컴파일러 작성자가 경고가 유용 할 것으로 기대하는 이유를 알지 못하고 <<에 대한 가변적 인 두 번째 피연산자에 대한 일반적인 경고로 인해 엄청난 양의 오 탐지가 발생합니다. –

+0

@onebyone :'int'가 32 비트이고'long long'이 64라고 가정하면'~ (foo + (1 << bar))'는'0 <= bar <32'에 대해서만 작동하며'~ (foo + (1LL << bar))'는'0 <= bar <64'에서 작동합니다. 나는 전자가 후자 대신에 쓸 때 OP가 경고를 원한다고 생각한다. – ephemient

+0

물론, foo가 int이고 bar가 논리적으로 (유형이 아닌) 1 또는 2로 제한되는 경우 경고를 원하겠습니까? foo가 긴 long이고 bar가 1 또는 2 인 곳은 어떨까요? 오버플로 결과가 정의되지 않았으므로 부호있는 상수에 막대를 곱하거나 추가하는 경고?컴파일러는 대개 논리적 제약 조건을 식별 할 수 없으므로 이러한 경고가 오 탐지 가능성이 높습니다. 나쁜 아이디어라는 것을 의미하지는 않습니다. 필자는 왜 이것이 무엇이되어야하는지 정의하기가 어렵고 어쨌든 컴파일러 작성자에게는 우선 순위가 낮다고 추측합니다. –

답변

1

이 의심스러운 것으로 신고 할 것이라는 것이 기본 조건인지 확실하지 않습니다. 바의 값이 보다 크고 int의 크기 (비트 단위)가 크다면 분명히 뭔가가 있지만, 일반적으로 컴파일러 은 알 수 없습니다. 휴리스틱 버그 검색 도구의 관점에서 볼 때, 일반 구조에서 가능성이있는 버그를 구분하는 데 좋은 패턴을 가진 은 너무 많은 false 포지티브를 피하기위한 열쇠입니다 (사용자가 도구를 싫어하고 사용을 거부 함) . 숫자 유형의 크기보다 큰하여 내 URL 플래그에

오픈 소스 도구는 논리 시프트하지만, 주로 중요한 임베디드 소프트웨어에 대한 검증 도구입니다 당신이 경우 작업 의 많은이 적절한 것으로 예상 연결된 구조와 다른 어려움으로 리눅스 커널 에서 사용하려고합니다.

+0

나는 당신의 웹 사이트를 보게 될 것입니다. 나는 64시에 술집을 제안함으로써 잘못 알고 있습니다. 그렇다하더라도 lint가 잡는 문제는 있지만 gcc가 잡으려고하는 것이 문제입니다. 문제는 너무 큰 변화가 아니며, 의도하지 않은 여러 유형의 복잡한 표현입니다. – talkaboutquality

관련 문제