2016-10-05 1 views
4

다음 코드를 고려하십시오. 내가 -Wconversion이 코드를 컴파일 할 경우더 넓은 정수 형식을 비트 필드로 안전하게 변환하려면 어떻게해야합니까?

#include <stdint.h> 

struct MaskAndCount{ 
    uint64_t occupied : 56; 
    uint8_t numOccupied : 8; 
}; 

int main(){ 
    int count = 7; 
    MaskAndCount foo; 
    foo.occupied &= ~(1L << count); 
} 

후 나는 다음과 같은 오류가 발생합니다.

g++ -Wconversion Main.cc 
Main.cc: In function ‘int main()’: 
Main.cc:11:18: warning: conversion to ‘long unsigned int:56’ from ‘long unsigned int’ may alter its value [-Wconversion] 
    foo.occupied &= ~(1L << count); 

이 합법적 인 문제가 될 것 같다,하지만 내 원하는 동작은 오른쪽에있는 값을 모두 더 높은 비트를 잘라내는 정확하게이다.

내 질문은 두 가지입니다.

  1. 작성된대로 변환하면 오른쪽에있는 값의 상위 비트가 잘리는 효과가 있습니까?
  2. 경고를 로컬로 보내지 않거나 경고를 트리거하지 않는 다른 구문으로 동일한 동작을 나타내는 방법이 있습니까?

나는 다음과 같은 정적 캐스트를 시도했지만, 전혀 컴파일되지 않습니다.

static_cast<uint64_t:56>(~(1L << count)) 
+0

유일한 옵션은 특정 경고를 끄는 것일 수 있습니다. 컴파일러를 어떻게 지정해야하는지 알고 싶다면. –

+0

@MarkRansom, 불행히도이 문장은 템플릿 파일의 헤더 파일에 나타나며 라이브러리를 작성하고 있으므로 라이브러리의 모든 사용자에게 경고 메시지를 표시하지 않도록 설정해야합니다. 내 라이브러리를 사용해 볼 의향이있는 응용 프로그램 집합입니다. – merlin2011

답변

3

마찬가지로 상단 비트 (설정되어있는 경우)는 무시됩니다.

당신은 할당하기 전에 상위 비트를 직접 제거하여 경고를 방지 할 수 있습니다

int count = 7; 
MaskAndCount foo = {}; 
           // chop off the top 8 bits 
foo.occupied &= ~(1 << count) & 0x00FFFFFFFFFFFFFFUL; 

편집 :가 (왜 확실하지)이 |= 작동하지 않습니다 밝혀졌습니다. 그러나 이는 |=을 피하고 정상적인 할당을 사용하여 수정할 수 있습니다.

foo.occupied = (foo.occupied & ~(1UL << count)) & 0x00FFFFFFFFFFFFFFUL; 
foo.occupied = (foo.occupied | ~(1UL << count)) & 0x00FFFFFFFFFFFFFFUL; 
+0

상수 끝에 'L'이 필요하지 않습니까? –

+0

@MarkRansom TBH 확실하지 않습니다. 상수는'long'이 될 수 없을만큼 길기 때문에 컴파일러가 알아낼 것이라고 가정했지만 아마 맞을 것입니다. – Galik

+0

불행히도 이것은'& = '대신'| ='를 사용하는 경우에는 작동하지 않지만 혼동을 피하기 위해 [새로운 질문] (http://stackoverflow.com/q/39882045/391161)을 요청했습니다. – merlin2011

관련 문제