source

C프로그램의 정수를 위한 역사적인 typedef 수프는 무엇이었나요?

goodcode 2022. 9. 23. 00:13
반응형

C프로그램의 정수를 위한 역사적인 typedef 수프는 무엇이었나요?

이것은 아마도 내가 답을 알아야 할 무의미한 질문이다.

의 15개의 정수 .#ifdef본되지 않는soup이 있는 것. 내가 본 모든 프로그램이나 라이브러리에는 서로 호환되지 않는 타입의 수프가 있는 것 같았다.그 당시에는 프로그래밍에 대해 잘 몰랐고 컴파일러에게 어떤 종류의 정수를 사용하고 싶은지 알려주는 것은 이상한 후프처럼 보였다.

나는 그 타이페프들이 무엇에 관한 것이었는지 설명하려고 마음속으로 이야기를 엮어봤지만 사실인지 모르겠다.기본적으로 C가 처음 개발되고 표준화되었을 때 플랫폼 독립적으로 특정 크기의 정수형을 얻을 수 있는 것이 얼마나 중요한지 깨닫지 못했기 때문에 플랫폼마다 원래의 C 정수형이 다를 수 있습니다.따라서 휴대용 C 코드를 작성하려는 모든 사람이 직접 작성해야 했습니다.

이거 맞는건가요?만약 그렇다면 프로그래머가 C 정수형을 어떻게 사용할 것으로 예상되었습니까?낮은 수준의 언어에서는 32비트 정수라고 말할 수 있는 게 중요하지 않을까요?그리고 1989년에 언어가 표준화되었기 때문에, 사람들이 휴대용 코드를 쓰려고 할 것이라는 생각이 분명히 있었다.

C가 처음 시작했을 때 컴퓨터는 오늘날보다 동질적이지 않았고 연결도 훨씬 더 낮았다.휴대성에서는 int 타입이 컴퓨터의 자연사이즈가 되는 것이 더 중요하다고 생각되었습니다.36비트 시스템에서 정확히 32비트 정수형을 요구하면 비효율적인 코드가 발생할 수 있습니다.

그 후, 특정의 무선 사이즈 필드에서 작업할 수 있는 광범위한 네트워킹이 도입되었습니다.상호 운용성은 크게 다릅니다.'옥텟'은 데이터 유형의 사실상의 양이 됩니다.

8비트의 정확한 배수의 ints가 필요하기 때문에 typedef soup을 사용할 수 있습니다.그리고 최종적으로 표준적인 이름을 사용할 수 있습니다.스프는 필요 이상으로 필요하지 않습니다.

C의 초기 성공은 다음과 같은 기능을 통해 기존의 거의 모든 변형 아키텍처에 적응할 수 있는 유연성 때문입니다.
1) 8, 16, 18, 24, 32, 36 등의 네이티브 정수 크기,
2) 형 2 2: 2의 보, 1의 보, 2의 부호 정수
3) 다양한 엔디언, 빅, 리틀

코딩이 개발됨에 따라 알고리즘과 데이터 교환은 보다 통일성을 높였고, 따라서 플랫폼 전체에서 위의 1과 2를 충족하는 유형의 필요성이 대두되었습니다. 것을 굴렸다.typedef int int32 a #if ...OP가 지적한 바와 같이 다양한 변형이 수프를 만들었습니다.


는 C99를 도입했습니다.(u)int_leastN_t, (u)int_fastN_t, (u)intmax_t최소 비트 너비 타입의 휴대성을 실현합니다.이러한 유형은 N = 8,16,32,64에 필요합니다.

또한 다음과 같은 반옵션 타입(아래 ** 참조)도 도입되었습니다.(u)intN_t2의 보완이어야 하며 패딩은 없어야 합니다.이러한 인기 있는 타입은, 정수를 묽게 하기 위해서 매우 폭넓게 사용되고 있습니다.


프로그래머들이 어떻게 C 정수형을 사용할 것으로 예상되었는가?

비트 폭에 크게 의존하지 않는 유연한 코드를 작성한다.은 가 꽤 .strtol()" "만 사용"LONG_MIN, LONG_MAX비트폭/엔디안/부호화에는 관계 없습니다.

그러나 많은 코딩 작업에서는 정밀한 폭 타입과 2의 보완을 통해 고성능 코딩을 쉽게 할 수 있습니다.이 경우 36비트 머신과 32비트 부호 크기의 머신으로의 이식성을 포기하고 2개의 와이드(서명된 2의 보완) 정수를 사용하는N 것이 좋습니다.다양한 CRC 및 암호 알고리즘과 파일 형식이 생각납니다.따라서 고정폭 타입과 이를 실현하기 위한 특정(C99) 방법이 필요합니다.


오늘날에도 여전히 관리해야 할 문제가 남아 있습니다.예제:통상적인 프로모션int/unsigned이 타입들은 16, 32, 64가 될 수 있기 때문에 컨트롤이 없어집니다.


**

이러한 유형은 옵션입니다.단, 구현이 너비가 8, 16, 32 또는 64비트이고 패딩 비트가 없으며 (서명된 형식에 대해) 2의 보완 표현을 가진 정수 형식을 제공하는 경우, 해당 형식 이름을 정의해야 한다.C11 7.20.1.1 정확한 폭의 정수 타입 3

C는 컴퓨팅 생태계가 크게 달랐던 1970년대 초반의 산물이다.수백만 대의 컴퓨터가 확장 네트워크를 통해 서로 통신하는 것이 아니라, 전 세계적으로 수십만 대의 시스템이 있으며, 각 시스템은 몇 개의 획일화된 애플리케이션을 실행하고 있으며, 시스템 간 통신은 거의 이루어지지 않았습니다.어떤 두 아키텍처도 같은 단어 크기를 가지고 있거나 부호 있는 정수를 같은 방식으로 표현한다고 가정할 수 없습니다.시장은 아직 충분히 작았기 때문에 표준화할 필요가 없었고, 컴퓨터는 서로 대화하지 않았으며(대부분), 휴대성에 대해서는 그다지 언급하지 않았습니다.

만약 그렇다면 프로그래머가 C 정수형을 어떻게 사용할 것으로 예상되었습니까?

최대한의 휴대용 코드를 작성하려면 표준이 보장하는 범위를 벗어나는 어떠한 것도 가정하지 않았습니다. int 것을 수 는 생각하지[-32767,32767]또한 2의 보완으로 표현된다고 가정하지도 않았고 특정 폭이라고 가정하지도 않았습니다(16비트보다 넓을 수 있지만 패딩 비트가 포함된 경우 16비트 범위만 나타냅니다).

휴대성에 관심이 없거나 본질적으로 휴대성이 없는 작업(일반적으로 약간 빈둥거리는 작업)을 하는 경우 요구 사항을 충족하는 모든 유형을 사용했습니다.

저는 주로 고급 어플리케이션 프로그래밍을 했기 때문에 표현에 대한 걱정이 범위보다 적었습니다.그래도 가끔 2진수 표현을 써야 하는데 그게 항상 나를 괴롭혔어.90년대 초에 MacOS, Windows 3.1 및 Solaris에서 실행해야 하는 코드를 작성한 기억이 있습니다.32비트 마스크에 대한 열거 상수를 많이 만들었습니다. Mac 및 Unix 상자에서는 정상적으로 작동했지만 Windows 상자에서는 컴파일하지 못했습니다.int폭이 16비트밖에 안 돼요

난 그 시기를 기억하고 있고 똑같은 짓을 한 게 죄야!

한 가지 문제는 의 규모였다.int, 같은 경우가 있습니다.short, 또는long또는 그 사이에.예를 들어 바이너리 파일 형식을 사용하는 경우 모든 것이 정렬되어야 합니다.바이트가 복잡한 것도 주문합니다.많은 개발자들이 게으른 길을 택하고 그냥 해냈다.fwrite숫자를 바이트 단위로 구분하는 대신 말이죠.기계들이 더 긴 단어로 업그레이드되자 지옥이 터졌다.그렇게typedef쉽게 고칠 수 있는 해킹이었어요

그 당시처럼 퍼포먼스가 문제가 된다면int기계에서 가장 빠른 자연 사이즈가 보장되지만 32비트가 필요하다면int그것보다 짧아서 전복될 위험이 있었어요.

C언어에서는sizeof()프리프로세서 단계에서는 해결할 수 없습니다.그 때문에, 작업이 복잡해졌습니다.#if sizeof(int) == 4예를들면.

개인적인 이유 중 일부는 어셈블러 언어 사고방식으로 작동했을 뿐이며, 무엇의 개념을 추상화하려 하지 않았다.short,int그리고.long를 위한 것입니다.당시 C에서는 어셈블러가 꽤 자주 사용되었습니다.

현재는 바이너리 이외의 파일 형식, JSON, XML 등이 많이 있습니다.또한 많은 인기 플랫폼이 32비트를 채택하고 있습니다.int대부분의 경우 이 정도면 충분하기 때문에 롤오버에 문제가 없습니다.

C는 가능한 한 폭넓은 머신에 이식할 수 있는 언어로서 설계되어 있습니다.대부분의 프로그램을 변경 없이 실행할 수 있는 언어가 아닙니다.대부분의 실무적 목적을 위해 C의 유형은 다음과 같다.

  • 8비트 타입이 있는 경우 또는 최소8비트인 최소 타입.

  • 16비트 타입(사용 가능한 경우) 또는 최소 16비트 타입.

  • 32비트 타입(사용 가능한 경우) 또는 32비트 이상의 타입.

  • 시스템이 16비트 타입과 같은 것을 효율적으로 처리할 수 있는 경우는 32비트, 그렇지 않은 경우는 16비트가 되는 타입.

코드가 8, 16 또는 32비트 타입을 필요로 하고, 그것들을 지원하지 않는 머신에서는 사용할 수 없을 것 같다면, 이러한 코드에는 다음과 같은 특별한 문제가 없습니다.char,short,그리고.long각각 8비트, 16비트 및 32비트로 표시됩니다.이러한 이름을 이러한 유형에 매핑하지 않은 유일한 시스템은 이러한 유형을 지원할 수 없고 해당 유형을 필요로 하는 코드를 유용하게 처리할 수 없는 시스템일 것입니다.이러한 시스템은 사용하는 유형과 호환되도록 작성된 코드 작성에 한정됩니다.

C는 시스템 사양을 언어 방언으로 변환하는 레시피로 보는 것이 가장 좋다고 생각합니다.36비트 메모리를 사용하는 시스템은 옥텟 기반 메모리를 사용하는 시스템과 같은 언어 사투리를 효율적으로 처리할 수 없지만, 하나의 사투리를 배우는 프로그래머는 후자가 사용하는 정수 표현을 배우는 것만으로 다른 사투리를 배울 수 있다.36비트 시스템의 코드를 작성해야 하는 프로그래머에게 "이 기계는 다른 기계와 똑같습니다.char9비트,short18비트이고long는, 「다른 언어에서는 모두 이 시스템이 효율적으로 처리할 수 없는 정수 타입이 필요하기 때문에, 어셈블리 언어를 사용할 필요가 있습니다」라고 하는 것과 같습니다.

모든 기계에 동일한 네이티브 워드 크기가 있는 것은 아닙니다.변수 크기가 작을수록 효율적이라고 생각할 수 있지만 실제로는 그렇지 않습니다.실제로 CPU의 네이티브 워드 크기와 동일한 크기의 변수를 사용하는 것이 산술, 논리 및 비트 조작에서 훨씬 더 빠릅니다.

하지만 정확히 '원어 크기'란 무엇일까요?이는 거의 항상 CPU의 레지스터 크기를 의미하며, 이는 산술논리유닛(ALU)에서 사용할 수 있는 것과 동일합니다.

임베디드 환경에서는 8비트 및 16비트 CPU가 여전히 존재합니다(4비트 PIC 컨트롤러가 아직 존재합니까?).32비트 프로세서는 아직 산더미처럼 많습니다.즉, "원어민 단어 크기"의 개념은 C developers에게 유효합니다.

64비트 프로세서의 경우 32비트 오퍼랜드가 적절히 지원되고 있는 경우가 많습니다.실제로는 32비트 정수와 부동소수점 값을 사용하는 것이 보통 전체 워드 크기보다 빠를 수 있습니다.

또, C구조를 배치하는 경우, 원어민 어라인먼트와 전체적인 메모리 소비량과의 트레이드오프가 있다.

다만, 사이즈에 구애받지 않는 코드(int, short, long)나 고정 사이즈(int32_t, int16_t, int64_t)의 2개의 일반적인 사용 패턴은 남아 있습니다.

언급URL : https://stackoverflow.com/questions/43407298/what-was-with-the-historical-typedef-soup-for-integers-in-c-programs

반응형