바이트 버퍼에 서명하거나 서명되지 않은 숯 버퍼를해야합니까?

StackOverflow https://stackoverflow.com/questions/653336

  •  19-08-2019
  •  | 
  •  

문제

바이트 버퍼가 숯 또는 서명되지 않은 숯 또는 단순히 숯 버퍼로 서명해야합니까? C와 C ++의 차이가 있습니까?

감사.

도움이 되었습니까?

해결책

바이트 버퍼가 숯 또는 서명되지 않은 숯 또는 단순히 숯 버퍼로 서명해야합니까? C와 C ++의 차이가 있습니까?

언어가 그것을 취급하는 방법에 대한 사소한 차이. ㅏ 거대한 컨벤션이 그것을 취급하는 방식의 차이.

  • char = ASCII (또는 UTF-8, 그러나 서명은 거기에 방해가됩니다) 텍스트 데이터
  • unsigned char = 바이트
  • signed char = 드물게 사용되지 않습니다

그리고 코드가 있습니다 의존합니다 그런 구별에. 불과 2 주 또는 2 주 전에 JPEG 데이터가 부패하여 버그가 발생하여 버그가 발생했습니다. char* Base64 Encode 함수의 버전-"유용한"모든 유효하지 않은 UTF-8을 "문자열"으로 대체했습니다. 변경 BYTE 일명 unsigned char 그것을 고치는 데 필요한 전부였습니다.

다른 팁

임의의 이진 데이터를 저장하려는 경우 사용해야합니다. unsigned char. C 표준에 의해 패딩 비트가 없음을 보장하는 유일한 데이터 유형입니다. 서로 다른 데이터 유형은 객체 표현에 패딩 비트를 포함 할 수 있습니다 (즉 값을 결정하는 대신 객체의 모든 비트를 포함하는 것). 패딩 비트의 상태는 지정되지 않으며 값을 저장하는 데 사용되지 않습니다. 따라서 사용을 읽는 경우 char 일부 바이너리 데이터, 사물은 숯의 값 범위로 줄어 듭니다 (값 비트 만 해석함으로써). 방금 무시되었지만 여전히 읽고 읽는 비트가 여전히있을 수 있습니다. memcpy. 실제 구조물 객체의 패딩 비트와 매우 흡사합니다. 유형 unsigned char 그것들을 포함하지 않도록 보장됩니다. 그것은 뒤 따릅니다 5.2.4.2.1/2 (C99 TC2, N1124 여기) :

char 유형 객체의 값이 표현식에 사용될 때 서명 된 정수로 취급되는 경우 CHAR_MIN 그것의 것과 동일해야합니다 SCHAR_MIN 그리고의 가치 CHAR_MAX 그것의 것과 동일해야합니다 SCHAR_MAX. 그렇지 않으면, 값 CHAR_MIN 0이고 값이어야합니다 CHAR_MAX 그것의 것과 동일해야합니다 UCHAR_MAX. 가치 UCHAR_MAX 동일해야합니다 2^CHAR_BIT − 1

마지막 문장에서 패딩 비트에 남은 공간이 없다는 것을 따릅니다. 사용하는 경우 char 버퍼의 유형으로, 당신은 또한 오버플로의 문제가 있습니다. 8 비트 - 따라서 그러한 과제가 괜찮을 것으로 기대할 수 있지만 char, 그것은 CHAR_MIN..CHAR_MAX, 이러한 변환은 신호 상승을 포함하여 구현 된 결과를 구현하고 구현 된 결과를 유발합니다.

위의 문제에 관한 문제는 아마도 실제 구현에 표시되지 않을 것입니다 ( 매우 구현 품질이 좋지 않음), 당신은 처음부터 올바른 유형을 사용하는 것이 가장 좋습니다. unsigned char.

그러나 문자열의 경우 선택의 데이터 유형은 char, 문자열 및 인쇄 기능으로 이해됩니다. 사용 signed char 이러한 목적을 위해 나에게 잘못된 결정처럼 보입니다.

자세한 내용은 읽으십시오 this proposal 다음 버전의 C 표준에 대한 수정이 포함되어 있으며 결국에는 필요합니다. signed char 패딩 비트도 없습니다. 이미에 통합되어 있습니다 작업 용지.

때에 따라 다르지.

버퍼가 텍스트를 고정하려는 경우, 아마도이를 배열로 선언하는 것이 합리적 일 것입니다. char 플랫폼이 기본적으로 서명했거나 서명되지 않은지를 결정하게하십시오. 예를 들어 구현의 런타임 라이브러리 안팎에서 데이터를 전달하는 데 어려움이 가장 적습니다.

버퍼가 이진 데이터를 보유하려는 경우, 사용 방법에 따라 다릅니다. 예를 들어, 이진 데이터가 실제로 8 비트 고정 지점 ADC 측정에 서명 된 데이터 샘플 배열 인 경우 signed char 가장 좋을 것입니다.

대부분의 실제 경우, 버퍼는 버퍼이며, 버퍼를 대량 조작으로 채우기 때문에 개별 바이트의 유형에 관심이 없으며,이를 전달하려고합니다. Parser는 복잡한 데이터 구조를 해석하고 유용한 것을 수행합니다. 이 경우 가장 간단한 방식으로 선언하십시오.

실제로 기본 기본 로케일의 문자열이 아닌 8 비트 바이트의 버퍼 인 경우 uint8_t. 숯이 바이트가 아닌 곳에는 많은 기계가 없지만 (또는 바이트 옥트), '이것은 문자열 인'것이 아니라 '이것은 옥제의 버퍼'라고 진술하는 것이 종종 유용한 문서입니다.

당신은 어느 쪽이든 사용해야합니다 또는 서명되지 않은 숯 그러나 결코 서명 숯. 표준은 3.9/2에서 다음과 같습니다

POD Type T의 모든 객체 (기본 클래스 서브 버젝트 제외)의 경우 객체가 유형 T의 유효한 값을 보유하든 아니든, 객체를 구성하는 기본 바이트 (1.7)는 char 또는 부호없는 배열로 복사 할 수 있습니다. char. char 또는 부호없는 char 배열의 내용이 객체로 다시 복사되는 경우, 객체는 그 후 원래 값을 유지해야합니다.

서명되지 않은 숯으로 정의하는 것이 좋습니다. FILACT Win32 유형 바이트는 서명되지 않은 숯으로 정의됩니다. 이것 사이에 C & C ++ 사이에는 차이가 없습니다.

최대의 이식성을 위해 항상 서명되지 않은 숯을 사용하십시오. 이것이 작용할 수있는 몇 가지 사례가 있습니다. Endian 유형이 다른 시스템 전체에서 공유되는 직렬화 된 데이터가 즉시 떠 오릅니다. 시프트 또는 비트 마스킹을 수행 할 때 값은 또 다른 것입니다.

int8_t vs uint8_t의 선택은 ptr을 null로 비교할 때와 유사합니다.


기능적 관점에서 NULL과 비교하는 것은 NULL이 0에 대한 #define이기 때문에 0과 비교하는 것과 동일합니다.

그러나 개인적으로, 코딩 스타일의 관점에서, 나는 null #define이 당신이 나쁜 포인터를 확인하는 코드를 유지하는 코드를 유지하는 사람과 내 포인터를 null과 비교하기로 선택합니다 ...

vs

누군가가 0과 비교할 때 특정 값을 확인하고 있음을 의미합니다.


위의 이유로, 나는 UINT8_T를 사용하겠습니다.

요소를 더 넓은 변수로 가져 오면 물론 부호 확장 여부가 될 것입니다.

해야 할 것입니다 ... 나는 경향이 있습니다 선호하다 서명되지 않은 것은 "원시"느낌이 들기 때문에 "이봐 요, 그건 작은 것입니다. ints", 데이터의 이진성을 강조하고 싶다면.

나는 명백한 것을 사용한 적이 없다고 생각합니다 signed char 바이트의 버퍼를 나타냅니다.

물론 세 번째 옵션 중 하나는 버퍼를 다음과 같이 표현하는 것입니다. void * 가능한 한 많이. 많은 일반적인 I/O 기능이 함께 작동합니다 void *, 때로는 어떤 정수 유형을 사용할 것인지 결정이 완전히 캡슐화 될 수 있습니다.

몇 년 전 저는 128 이상의 ASCII 값에 대해 색상 숯을 인쇄하는 C ++ 콘솔 애플리케이션에 문제가 있었으며, 이것은 숯에서 서명되지 않은 숯으로 전환하여 해결되었지만 숯 유형을 유지하면서 용서가되었다고 생각합니다.

현재 대부분의 C/C ++ 기능은 Char를 사용하며 이제 두 언어를 훨씬 더 잘 이해하므로 대부분의 경우 Char를 사용합니다.

정말로 신경 쓰나요? 그렇지 않은 경우 기본값 (char)을 사용하고 중요하지 않은 문제로 코드를 혼란스럽게하지 마십시오. 그렇지 않으면, 미래의 관리자는 왜 서명 (또는 서명되지 않은)을 사용했는지 궁금해 할 것입니다. 그들의 삶을 더 간단하게 만드십시오.

컴파일러에 누워 있으면 처벌 할 것입니다.

버퍼에 버퍼에 방금 통과되는 데이터가 포함되어 있고 어떤 식 으로든 조작하지 않으면 중요하지 않습니다.

그러나 버퍼 내용에서 작동 해야하는 경우 올바른 유형 선언이 코드를 더 간단하게 만듭니다. "int val = buf [i] & 0xff;" 무의미한 말.

따라서 실제로 데이터가 무엇인지, 어떻게 사용해야하는지 생각해보십시오.

typedef char byte;

이제 배열을 만들 수 있습니다 byte에스. 모든 사람에게 당신이 의미하는 바를 분명히하고 기능을 잃지 않습니다.

나는 그것이 다소 어리 석다는 것을 알고 있지만, 의도 한대로 코드를 100% 읽게합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top