태그 보관물: c

c

signed int 대신 unsigned를 사용하면 버그가 발생할 가능성이 더 큽니까? 왜? 식 산술 (오버플로 / 언더 플로에서

에서 구글 C ++ 스타일 가이드 “부호없는 정수”의 주제에, 그것은하는 것이 좋습니다

역사적 사고로 인해 C ++ 표준은 컨테이너의 크기를 나타 내기 위해 부호없는 정수를 사용합니다. 표준기구의 많은 구성원은 이것이 실수라고 생각하지만이 시점에서 수정하는 것은 사실상 불가능합니다. 부호없는 산술은 단순한 정수의 동작을 모델링하지 않고 대신 모듈 식 산술 (오버플로 / 언더 플로에서 래핑)을 모델링하기 위해 표준에 의해 정의된다는 사실은 컴파일러에서 중요한 버그 클래스를 진단 할 수 없음을 의미합니다.

모듈 식 산술의 문제점은 무엇입니까? unsigned int의 예상되는 동작이 아닙니까?

이 가이드에서는 어떤 종류의 버그 (중요한 클래스)를 언급합니까? 범람하는 버그?

부호없는 유형을 사용하여 변수가 음수가 아니라고 단언하지 마십시오.

내가 unsigned int보다 signed int를 사용하는 것을 생각할 수있는 한 가지 이유는 그것이 오버플로 (음수로)되면 감지하기 더 쉽기 때문입니다.



답변

답변 중 일부는 여기에 서명 부호없는 값 사이의 놀라운 프로모션 규칙을 언급하지만 더 많은 관련 문제처럼 보인다 혼합 서명과 서명되지 않은 값을, 왜 반드시 설명하지 않습니다 서명 변수가 선호 될 것이다 서명되지 않은 시나리오를 혼합의 외부.

내 경험상 혼합 비교와 승격 규칙 외에 부호없는 값이 다음과 같이 버그 자석 인 두 가지 주요 이유가 있습니다.

부호없는 값은 프로그래밍에서 가장 일반적인 값인 0에서 불연속성을 갖습니다.

부호없는 정수와 부호있는 정수는 모두 최소값과 최대 값에서 불연속성 을 가지며, 여기에서 줄 바꿈 (부호 없음)하거나 정의되지 않은 동작 (부호 있음)을 유발합니다. 들어 unsigned이러한 점에있다 제로UINT_MAX. 들어 int가에있다 INT_MIN하고 INT_MAX. 전형적인 값 INT_MININT_MAX4 바이트로 시스템 int값은 다음 -2^312^31-1, 이러한 시스템에서 UINT_MAX일반적이다 2^32-1.

unsigned적용되지 않는 주요 버그 유발 문제 는 0에서 불연속성int 이 있다는 것 입니다. 물론 0은 1,2,3과 같은 다른 작은 값과 함께 프로그램에서 매우 일반적인 값입니다. 다양한 구조에서 작은 값, 특히 1을 더하고 빼는 것이 일반적이며, 값에서 어떤 것을 빼고 0이된다면 엄청난 양의 값과 거의 확실한 버그를 얻게됩니다.unsigned

마지막 0.5를 제외하고 인덱스별로 벡터의 모든 값을 반복하는 코드를 고려하십시오 .

for (size_t i = 0; i < v.size() - 1; i++) { // do something }

이것은 언젠가 빈 벡터를 전달할 때까지 잘 작동합니다. 0 반복을 수행하는 대신 v.size() - 1 == a giant number1 을 얻고 40 억 반복을 수행하고 거의 버퍼 오버플로 취약성을 갖습니다.

다음과 같이 작성해야합니다.

for (size_t i = 0; i + 1 < v.size(); i++) { // do something }

따라서이 경우 “고정”될 수 있지만의 서명되지 않은 특성에 대해 신중하게 생각해야만합니다 size_t. 때로는 상수 대신 적용하려는 변수 오프셋이 있기 때문에 위의 수정을 적용 할 수없는 경우도 있습니다. 이는 양수 또는 음수 일 수 있습니다. 따라서 비교해야하는 “측”은 부호에 따라 달라집니다. -이제 코드가 정말 지저분 해집니다.

0까지 반복하는 코드에도 비슷한 문제가 있습니다. 같은 것은 while (index-- > 0)잘 작동하지만 분명히 동등한 while (--index >= 0)것은 서명되지 않은 값으로 종료되지 않습니다. 컴파일러는 오른쪽이 리터럴 0 일 때 경고 할 수 있지만 런타임에 결정된 값이면 확실히 그렇지 않습니다.

대위법

어떤 사람들은 부호있는 값에도 두 개의 불연속성이 있다고 주장 할 수 있는데, 왜 unsigned를 선택합니까? 차이점은 두 불연속 모두 0에서 매우 (최대) 멀리 떨어져 있다는 것입니다. 저는 이것을 “오버플로”라는 별도의 문제로 생각합니다. 부호있는 값과 부호없는 값 모두 매우 큰 값에서 오버플로 될 수 있습니다. 많은 경우 값의 가능한 범위에 대한 제약으로 인해 오버플로가 불가능하고 많은 64 비트 값의 오버플로가 물리적으로 불가능할 수 있습니다. 가능하더라도 오버플로 관련 버그의 가능성은 “0에서”버그에 비해 종종 미미 하며 부호없는 값에 대해서도 오버플로가 발생합니다 . 따라서 unsigned는 두 세계의 최악을 결합합니다. 잠재적으로 매우 큰 크기 값으로 오버플로되고 0에서 불연속됩니다. 서명은 전자 만 있습니다.

많은 사람들이 서명하지 않은 상태에서 “당신은 조금 잃는다”고 주장 할 것입니다. 이것은 종종 사실이지만 항상 그런 것은 아닙니다 (부호없는 값 사이의 차이를 나타내야하는 경우 어쨌든 해당 비트를 잃게됩니다. 너무 많은 32 비트 항목이 어쨌든 2GiB로 제한되거나 이상한 회색 영역이 표시됩니다. 파일은 4GiB 일 수 있지만 두 번째 2GiB 절반에서는 특정 API를 사용할 수 없습니다.

unsigned가 당신을 조금 사주는 경우에도 : 그것은 당신을 많이 사주지 않습니다. 만약 당신이 20 억 개 이상의 “사물”을 지원해야한다면, 아마도 곧 40 억 개 이상을 지원해야 할 것입니다.

논리적으로 부호없는 값은 부호있는 값의 하위 집합입니다.

수학적으로 부호없는 값 (음이 아닌 정수)은 부호있는 정수 (_ 정수라고 함)의 하위 집합입니다. 2 . 그러나 부호있는 값 은 빼기와 같이 부호없는 값 에서만 연산에서 자연스럽게 튀어 나옵니다 . 부호없는 값은 빼기로 닫히지 않는다고 말할 수 있습니다 . 부호있는 값도 마찬가지입니다.

파일에있는 두 개의 서명되지 않은 인덱스 사이의 “델타”를 찾고 싶습니까? 뺄셈을 올바른 순서로하는 것이 좋습니다. 그렇지 않으면 잘못된 답을 얻을 수 있습니다. 물론 올바른 순서를 결정하기 위해 종종 런타임 검사가 필요합니다! 부호없는 값을 숫자로 처리 할 때 (논리적으로) 부호있는 값이 계속 표시되므로 부호있는 값으로 시작하는 것이 좋습니다.

대위법

위의 각주 (2)에서 언급했듯이 C ++의 부호있는 값은 실제로 동일한 크기의 부호없는 값의 하위 집합이 아니므로 부호없는 값은 부호있는 값과 동일한 수의 결과를 나타낼 수 있습니다.

사실이지만 범위가 덜 유용합니다. 뺄셈과 0 ~ 2N 범위의 부호없는 숫자와 -N ~ N 범위의 부호있는 숫자를 고려합니다. 임의의 뺄셈은 _ 두 경우 모두 -2N ~ 2N 범위의 결과를 가져 오며 두 가지 유형의 정수 모두 다음을 나타낼 수 있습니다. 그것의 절반. -N에서 N까지의 0을 중심으로하는 영역은 일반적으로 0에서 2N 범위보다 훨씬 더 유용합니다 (실제 코드에서 더 많은 실제 결과를 포함 함). 균일 (log, zipfian, normal 등) 이외의 일반적인 분포를 고려하고 해당 분포에서 무작위로 선택된 값을 빼는 것을 고려하십시오. [0, 2N]보다 더 많은 값이 [-N, N]으로 끝나는 방식 (실제로 결과 분포) 항상 0에 중심).

64 비트는 부호있는 값을 숫자로 사용하는 많은 이유에서 문을 닫습니다.

나는 인수가 위에서 이미 32 비트 값에 대한 강력한라고 생각하지만, 모두 서명하고 서로 다른 임계 값에 부호없는 영향을 미치는 오버 플로우의 경우는 않는다 “20 억은”많은 초과 할 수있는 숫자이기 때문에, 32 비트 값을 발생 추상 및 물리적 양 (수십억 달러, 수십억 나노초, 수십억 개의 요소가있는 어레이). 따라서 누군가가 unsigned 값에 대해 양의 범위를 두 배로 늘려서 충분히 확신한다면 오버플로가 중요하고 unsigned를 약간 선호하는 경우를 만들 수 있습니다.

특수 도메인 외부에서 64 비트 값은이 문제를 크게 제거합니다. 10 개 이상 – 64 비트 서명 된 값 9,223,372,036,854,775,807의 상부 범위가 quintillion를 . 그것은 많은 나노초 (약 292 년 가치)와 많은 돈입니다. 또한 오랜 시간 동안 일관된 주소 공간에 RAM이있는 컴퓨터보다 더 큰 어레이입니다. 그렇다면 아마 9 천경이면 모두에게 충분할까요 (현재로서는)?

부호없는 값을 사용하는 경우

스타일 가이드는 부호없는 숫자의 사용을 금지하거나 반드시 권장하지 않습니다. 결론은 다음과 같습니다.

부호없는 유형을 사용하여 변수가 음수가 아니라고 단언하지 마십시오.

실제로 부호없는 변수에 대한 좋은 용도가 있습니다.

  • N- 비트 수량을 정수가 아니라 단순히 “비트 모음”으로 처리하려는 경우. 예를 들어, 비트 마스크 나 비트 맵, N 부울 값 등으로. 이 사용은 종종 변수의 정확한 크기를 알고 싶어하기 때문에 uint32_t및 같은 고정 너비 유형과 함께 사용됩니다 uint64_t. 특정 변수가이 치료를받을 권리가 있다는 힌트는 단지와 함께에서 작동한다는 것입니다 비트 와 같은 통신 사업자 ~, |, &, ^, >>등, 그리고 같은 산술 연산과 +, -, *, /

    비트 연산자의 동작이 잘 정의되고 표준화되어 있기 때문에 Unsigned가 이상적입니다. 부호있는 값에는 이동시 정의되지 않은 동작과 지정되지 않은 동작, 지정되지 않은 표현과 같은 몇 가지 문제가 있습니다.

  • 실제로 모듈 식 산술을 원할 때. 때로는 실제로 2 ^ N 모듈 식 산술을 원합니다. 이 경우 “오버플로”는 버그가 아니라 기능입니다. 부호없는 값은 모듈 식 산술을 사용하도록 정의되었으므로 여기에서 원하는 것을 제공합니다. 부호있는 값은 지정되지 않은 표현이 있고 오버플로가 정의되지 않았기 때문에 (쉽고 효율적으로) 전혀 사용할 수 없습니다.


0.5 내가 이것을 쓴 후에 나는 이것이 내가 보지 못했던 Jarod의 예 와 거의 동일하다는 것을 깨달았습니다. 그리고 좋은 이유로 좋은 예입니다!

1 우리는 size_t여기서 말하는 것이므로 일반적으로 32 비트 시스템에서는 2 ^ 32-1, 64 비트 시스템에서는 2 ^ 64-1입니다.

2 C ++에서는 부호없는 값이 해당 부호있는 유형보다 상단에 더 많은 값을 포함하기 때문에 정확히 그렇지는 않지만 부호없는 값을 조작하면 (논리적으로) 부호있는 값이 생성 될 수 있다는 기본적인 문제가 있지만 해당 문제는 없습니다. 부호있는 값 포함 (부호있는 값에는 이미 부호없는 값이 포함되어 있으므로)


답변

언급했듯이 혼합 unsignedsigned (잘 정의 된 경우에도) 예상치 못한 동작이 발생할 수 있습니다.

마지막 5 개를 제외한 벡터의 모든 요소를 ​​반복한다고 가정하면 다음과 같이 잘못 작성할 수 있습니다.

for (int i = 0; i < v.size() - 5; ++i) { foo(v[i]); } // Incorrect
// for (int i = 0; i + 5 < v.size(); ++i) { foo(v[i]); } // Correct

가정 v.size() < 5으로, 다음, v.size()이다 unsigned, s.size() - 5매우 많은 수의 것, 그래서 i < v.size() - 5true의 가치를 더 예상 범위 i. 그리고 UB는 빠르게 발생합니다 (한 번i >= v.size() )

v.size()부호있는 값을 반환 하면s.size() - 5 음수가되고 위의 경우 조건은 즉시 거짓이됩니다.

반면에 인덱스는 사이에 [0; v.size()[있어야 unsigned하므로 의미가 있습니다. Signed는 또한 음수 부호의 오른쪽 시프트에 대한 오버플로 또는 구현 정의 동작이있는 UB로 자체 문제가 있지만 반복에 대한 버그의 원인은 적습니다.


답변

가장 큰 오류의 예 중 하나는 부호있는 값과 부호없는 값을 혼합하는 경우입니다.

#include <iostream>
int main()  {
    auto qualifier = -1 < 1u ? "makes" : "does not make";
    std::cout << "The world " << qualifier << " sense" << std::endl;
}

출력 :

세상이 말이 안돼

사소한 응용 프로그램이없는 한, 서명 된 값과 서명되지 않은 값 사이에 위험한 혼합 (런타임 오류 발생)이 발생하거나 경고를 크랭크업하여 컴파일 타임 오류로 만들면 결국 많은 코드의 static_casts. 그렇기 때문에 수학 또는 논리적 비교를 위해 유형에 부호있는 정수를 엄격하게 사용하는 것이 가장 좋습니다. 비트 마스크 및 비트를 나타내는 유형에만 unsigned를 사용하십시오.

숫자 값의 예상 도메인을 기반으로 부호없는 유형을 모델링하는 것은 나쁜 생각입니다. 대부분의 숫자는 20 억보다 0에 가까우므로 부호없는 유형의 경우 많은 값이 유효한 범위의 가장자리에 더 가깝습니다. 설상가상으로 최종 값은 알려진 양의 범위에있을 수 있지만 표현식을 평가하는 동안 중간 값이 언더 플로 될 수 있으며 중간 형식으로 사용되는 경우 매우 잘못된 값이 될 수 있습니다. 마지막으로, 값이 항상 양수일 것으로 예상 되더라도 음수 있는 다른 변수 와 상호 작용하지 않는다는 의미는 아니므로 부호있는 유형과 부호없는 유형을 혼합하는 강제 상황이 발생합니다. 최악의 장소.


답변

unsigned int를 사용하는 것이 signed int를 사용하는 것보다 버그를 일으킬 가능성이 더 높은 이유는 무엇입니까?

서명되지 않은 유형을 사용하는 것은 특정 작업 클래스에 서명 된 유형을 사용하는 것보다 버그를 일으킬 가능성이 더 큽니다 .

작업에 적합한 도구를 사용하십시오.

모듈 식 산술의 문제점은 무엇입니까? unsigned int의 예상되는 동작이 아닙니까?
unsigned int를 사용하는 것이 signed int를 사용하는 것보다 버그를 일으킬 가능성이 더 높은 이유는 무엇입니까?

작업이 잘 일치하는 경우 : 잘못된 것은 없습니다. 아니, 그럴 것 같지는 않다.

보안, 암호화 및 인증 알고리즘은 서명되지 않은 모듈 식 수학을 사용합니다.

압축 / 압축 해제 알고리즘과 다양한 그래픽 형식도 이점이 있으며 서명되지 않은 경우 버그가 적습니다. 수학에서 .

비트 연산자와 시프트가 사용될 때마다 부호없는 연산은 부호있는 수학 의 부호 확장 문제로 엉망이되지 않습니다 .


부호있는 정수 수학은 코딩에 대한 학습자를 포함한 모든 사람이 쉽게 이해할 수있는 직관적 인 모양과 느낌을 가지고 있습니다. C / C ++는 원래 대상이 아니 었으며 지금은 소개 언어가되어서는 안됩니다. 오버플로와 관련된 안전망을 사용하는 신속한 코딩의 경우 다른 언어가 더 적합합니다. 간결하고 빠른 코드의 경우 C는 코더가 자신이하는 일을 알고 있다고 가정합니다 (경험이 있음).

오늘날 부호있는 수학 의 함정은 유비쿼터스 32 비트로 int, 너무 많은 문제가있어 범위 검사없이 일반적인 작업을 수행하기에 충분히 넓습니다. 이것은 오버플로가 코딩되지 않는 안일함으로 이어집니다. 대신 for (int i=0; i < n; i++) int len = strlen(s);때문에 OK로 볼 n가정 < INT_MAX문자열이 너무 오래,보다는 전체 첫 번째 경우에 보호 또는 사용하여 원거리 될 수 없으며 size_t, unsigned심지어 long long2 년.

16 비트 int와 32 비트가 포함 된 시대에 개발 된 C / C ++ 와 서명되지 않은 16 비트가 size_t제공 하는 추가 비트 는 중요했습니다. 주의는 문제가 될 오버 플로우 관련하여 필요했다 intunsigned.

16 비트가 아닌 int/unsigned플랫폼에서 Google의 32 비트 (또는 더 넓은) 애플리케이션을 사용 int하면 충분한 범위 를 고려할 때 +/- 오버플로 에 대한 주의가 부족 합니다. 이러한 응용 프로그램을 장려하기 위해이 말이 intunsigned. 그러나 int수학은 잘 보호되지 않습니다.

좁은 16 비트 int/unsigned문제는 오늘날 일부 임베디드 애플리케이션에 적용됩니다.

Google의 지침은 오늘날 작성하는 코드에 잘 적용됩니다. 더 넓은 범위의 C / C ++ 코드에 대한 명확한 지침이 아닙니다.


내가 unsigned int보다 signed int를 사용하는 것을 생각할 수있는 한 가지 이유는 그것이 오버플로 (음수로)되면 감지하기 더 쉽기 때문입니다.

C / C ++에서 부호있는 int 수학 오버플로는 정의되지 않은 동작 이므로 서명되지 않은 수학의 정의 된 동작보다 감지하기가 확실히 쉽지 않습니다 .


따라 @ 크리스 Uzdavinis가 아니라 주석, 혼합 서명부호는 최고의 모든 (특히 초보자)에 의해 피할 필요로 할 때, 그렇지 않으면주의 깊게 코딩된다.


답변

저는 Google의 스타일 가이드 인 AKA the Hitchhiker ‘s Guide to Insane Directives from the Bad Programmers Who Got into the Long Time Ago에 대한 경험이 있습니다. 이 특정 지침은 그 책에있는 수십 가지의 열매 규칙 중 하나 일뿐입니다.

부호없는 유형으로 산술을 수행하려는 경우에만 오류가 발생합니다 (위의 Chris Uzdavinis 예제 참조), 즉 숫자로 사용하는 경우 오류가 발생합니다. 서명되지 않은 유형은 숫자 수량을 저장하는 데 사용되는 것이 아니라 음수가 될 수없는 컨테이너 크기와 같은 개수 를 저장하기위한 것이며 해당 목적으로 사용할 수 있고 사용해야합니다.

컨테이너 크기를 저장하기 위해 산술 유형 (예 : 부호있는 정수)을 사용하는 아이디어는 바보입니다. 목록의 크기를 저장하기 위해 double을 사용 하시겠습니까? Google에 산술 유형을 사용하여 컨테이너 크기를 저장하고 다른 사람들에게 동일한 작업을 요구하는 사람들이 있다는 것은 회사에 대해 뭔가를 말해줍니다. 그러한 지시에 대해 제가 알아 차린 한 가지는 그들이 바보 일수록 더 엄격한 규칙을해야한다는 것입니다. 그렇지 않으면 상식을 가진 사람들이 규칙을 무시할 것이기 때문입니다.


답변

부호없는 형식을 사용하여 음이 아닌 값을 나타냅니다 …

  • 다른 답변이 자세히 설명하고 논의 하듯이 부호있는 값과 부호없는 값을 사용할 때 유형 승격과 관련된 버그를 일으킬 가능성더 높지만
  • 바람직 하지 않거나 허용되지 않는 값을 나타낼 수있는 도메인을 가진 유형 선택과 관련된 버그를 일으킬 가능성적습니다 . 어떤 곳에서는 가치가 도메인에 있다고 가정하고 다른 가치가 어떻게 든 몰래 들어 오면 예상치 못한 잠재적으로 위험한 행동이 발생할 수 있습니다.

Google 코딩 가이드 라인은 첫 번째 고려 사항에 중점을 둡니다. C ++ Core Guidelines 와 같은 다른 지침 세트 는 두 번째 요점을 더 강조합니다. 예를 들어 핵심 가이드 라인 I.12를 고려하십시오 .

I.12 : null이 아니어야하는 포인터를 다음과 같이 선언합니다. not_null

이유

nullptr 오류를 역 참조하지 않도록합니다. 에 대한 중복 검사를 방지하여 성능을 향상시킵니다 nullptr.

int length(const char* p);            // it is not clear whether length(nullptr) is valid
length(nullptr);                      // OK?
int length(not_null<const char*> p);  // better: we can assume that p cannot be nullptr
int length(const char* p);            // we must assume that p can be nullptr

소스에 의도를 명시함으로써 구현 자와 도구는 정적 분석을 통해 일부 오류 클래스를 찾는 것과 같은 더 나은 진단을 제공하고 분기 제거 및 널 테스트와 같은 최적화를 수행 할 수 있습니다.

물론, non_negative두 범주의 오류를 모두 방지 하는 정수용 래퍼에 대해 주장 할 수 있지만 자체 문제가 있습니다.


답변

Google 문은 컨테이너의 크기 유형으로 서명되지 않음을 사용 하는 것에 관한 것입니다. 입니다. 대조적으로 질문은 더 일반적으로 보입니다. 계속 읽는 동안 명심하십시오.

지금까지 대부분의 답변이 Google 진술에 반응했기 때문에 더 큰 질문에는 덜 반응했기 때문에 음수 컨테이너 크기에 대한 답변을 시작하고 나중에 서명되지 않은 것이 좋다고 누구에게나 설득하려고 노력할 것입니다.

서명 된 컨테이너 크기

누군가가 버그를 코딩하여 부정적인 컨테이너 인덱스를 생성했다고 가정 해 보겠습니다. 결과는 정의되지 않은 동작 또는 예외 / 액세스 위반입니다. 인덱스 유형이 서명되지 않았을 때 정의되지 않은 동작이나 예외 / 액세스 위반을 얻는 것보다 정말 낫습니까? 아니에요.

이제 수학에 대해 이야기하고이 맥락에서 “자연스러운”것이 무엇인지 말하는 것을 좋아하는 부류의 사람들이 있습니다. 음수를 갖는 정수 유형이 본질적으로> = 0 인 무언가를 설명하는 데 어떻게 자연 스러울 수 있습니까? 음수 크기의 배열을 많이 사용하십니까? IMHO, 특히 수학적 경향이있는 사람들은 이러한 의미의 불일치 (크기 / 인덱스 유형은 음수가 가능하다고 말하는 반면 음의 크기 배열은 상상하기 어렵습니다)를 짜증나게 할 것입니다.

따라서이 문제에 대한 유일한 질문은 Google 주석에서 언급했듯이 컴파일러가 실제로 그러한 버그를 찾는 데 적극적으로 도움을 줄 수 있는지 여부입니다. 그리고 서명되지 않은 정수를 언더 플로 보호하는 대안보다 훨씬 좋습니다 (x86-64 어셈블리 및 다른 아키텍처에는이를 달성 할 수단이있을 수 있지만 C / C ++ 만 이러한 수단을 사용하지 않습니다). 내가 추측 할 수있는 유일한 방법은 컴파일러가 런타임 검사 ( if (index < 0) throwOrWhatever)를 자동으로 추가 하거나 컴파일 시간 작업의 경우 잠재적으로 많은 오 탐지 경고 / 오류를 생성하는 경우입니다. “이 배열 액세스에 대한 인덱스는 음수가 될 수 있습니다.” 의심 스럽지만 도움이 될 것입니다.

또한 실제로 런타임 검사를 작성하여 배열 / 컨테이너 인덱스를 작성하는 사람들은 부호있는 정수를 다루는 작업 이 더 많습니다 . 작성하는 대신 if (index < container.size()) { ... }이제 작성 해야 if (index >= 0 && index < container.size()) { ... }합니다.. 나에게 강제 노동처럼 보이며 개선이 아닌 것 같습니다 …

서명되지 않은 유형이없는 언어는 짜증납니다 …

예, 이것은 자바에서 찌르는 것입니다. 이제 저는 임베디드 프로그래밍 배경에서 왔으며 바이너리 연산 (및 / 또는 xor, …)과 비트 현명한 값 구성이 말 그대로 빵과 버터 인 필드 버스로 많은 작업을했습니다. 우리 제품 중 하나에 대해 우리 또는 오히려 고객은 자바 포트를 원했습니다. 그는 침착 함을 유지하려고 노력했고 침묵 속에서 고통 받았습니다 … 그러나 고통은 거기에 있었고, 서명되지 않은 정수 값을 지속적으로 처리 한 며칠 후에 저주를 멈출 수 없었습니다. 이러한 시나리오는 고통스럽고 개인적으로 Java가 부호있는 정수를 생략하고 부호없이 제공했다면 Java가 더 나았을 것이라고 생각합니다. 적어도 부호 확장 등에 대해서는 신경 쓸 필요가 없습니다.

이것들은 문제에 대한 나의 5 센트입니다.