저는 K & R의 “The C Programming Language” 를 읽고이 문장을 보았습니다. [Introduction, p. 삼]:
C에서 제공하는 데이터 유형과 제어 구조는 대부분의 컴퓨터 에서 직접 지원되기 때문에 자체 포함 프로그램을 구현하는 데 필요한 런타임 라이브러리는 매우 작습니다.
굵은 글씨는 무엇을 의미합니까? 컴퓨터에서 직접 지원 하지 않는 데이터 유형 또는 제어 구조의 예가 있습니까?
저는 K & R의 “The C Programming Language” 를 읽고이 문장을 보았습니다. [Introduction, p. 삼]:
C에서 제공하는 데이터 유형과 제어 구조는 대부분의 컴퓨터 에서 직접 지원되기 때문에 자체 포함 프로그램을 구현하는 데 필요한 런타임 라이브러리는 매우 작습니다.
굵은 글씨는 무엇을 의미합니까? 컴퓨터에서 직접 지원 하지 않는 데이터 유형 또는 제어 구조의 예가 있습니까?
답변:
예, 직접 지원되지 않는 데이터 유형이 있습니다.
많은 임베디드 시스템에는 하드웨어 부동 소수점 단위가 없습니다. 따라서 다음과 같은 코드를 작성할 때 :
float x = 1.0f, y = 2.0f;
return x + y;
다음과 같이 번역됩니다.
unsigned x = 0x3f800000, y = 0x40000000;
return _float_add(x, y);
그런 다음 컴파일러 또는 표준 라이브러리는 _float_add()
임베디드 시스템에서 메모리를 차지하는 의 구현을 제공 해야합니다. 정말 작은 시스템에서 바이트를 세는 경우이 값이 추가 될 수 있습니다.
또 다른 일반적인 예는 long long
32 비트 시스템에서 직접 지원되지 않는 64 비트 정수 ( 1999 년 이후 C 표준)입니다. 구형 SPARC 시스템은 정수 곱셈을 지원하지 않았기 때문에 런타임에서 곱셈을 제공해야했습니다. 다른 예가 있습니다.
이에 비해 다른 언어에는 더 복잡한 기본 형식이 있습니다.
예를 들어 Lisp 기호는 Lua의 테이블, Python의 문자열, Fortran의 배열 등과 같이 많은 런타임 지원이 필요합니다. C의 동등한 유형은 일반적으로 표준 라이브러리의 일부가 아니거나 (표준 기호 또는 테이블 없음) 훨씬 더 간단하고 많은 런타임 지원이 필요하지 않습니다 (C의 배열은 기본적으로 포인터 일 뿐이며 nul로 끝나는 문자열은 거의 간단합니다).
C에서 누락 된 주목할만한 제어 구조는 예외 처리입니다. 비 로컬 종료는 프로세서 상태의 특정 부분을 저장하고 복원하는 setjmp()
및 로 제한됩니다 longjmp()
. 이에 비해 C ++ 런타임은 스택을 탐색하고 소멸자 및 예외 처리기를 호출해야합니다.
사실,이 소개의 내용은 Kernighan과 Ritchie가 책의 초판에 처음 썼던 1978 년 이후 크게 변하지 않았을 것입니다. 그리고 그들은 현대보다 그 당시 C의 역사와 진화를 언급합니다. 구현.
컴퓨터는 기본적으로 메모리 뱅크와 중앙 프로세서 일 뿐이며 각 프로세서는 기계 코드를 사용하여 작동합니다. 각 프로세서 설계의 일부는 어셈블리 언어 라고하는 명령어 세트 아키텍처로, 사람이 읽을 수있는 니모닉 세트에서 모든 숫자 인 기계어 코드로 일대일로 매핑됩니다.
C 언어의 작성자와 바로 앞의 B 및 BCPL 언어는 가능한 한 효율적으로 Assembly로 컴파일 된 언어로 구문을 정의하려고했습니다. 사실, 그들은 대상의 제한에 의해 강제되었습니다. 하드웨어. 다른 답변에서 지적했듯이 여기에는 분기 (GOTO 및 C의 기타 흐름 제어), 이동 (할당), 논리 연산 (& | ^), 기본 산술 (더하기, 빼기, 증가, 감소) 및 메모리 주소 지정 (포인터 ). 좋은 예는 C의 pre- / post-increment 및 decrement 연산자입니다.이 연산자는 컴파일 된 후 단일 opcode로 직접 변환 할 수 있었기 때문에 Ken Thompson이 B 언어에 추가 한 것으로 추정됩니다.
이것이 저자들이 "대부분의 컴퓨터에서 직접 지원한다"는 말의 의미입니다. 다른 언어에 직접 지원 되지 않는 유형과 구조가 포함되어 있다는 의미가 아니라 설계 상 C 구조 가 어셈블리로 가장 직접 (때로는 문자 그대로 직접) 번역 .
구조화 된 프로그래밍에 필요한 모든 요소를 제공하면서도 기본 어셈블리와의 밀접한 관계는 C를 조기 채택하게했으며, 코드 컴파일의 효율성이 여전히 핵심 인 환경에서 오늘날 널리 사용되는 언어로 유지되었습니다.
언어의 역사에 대한 흥미로운 글은 The Development of the C Language-Dennis Ritchie를 참조하십시오 .
짧은 대답은 C에서 지원하는 대부분의 언어 구조는 대상 컴퓨터의 마이크로 프로세서에서도 지원되므로 컴파일 된 C 코드는 마이크로 프로세서의 어셈블리 언어로 매우 훌륭하고 효율적으로 변환되므로 코드와 설치 공간이 더 작아집니다.
더 긴 대답은 약간의 어셈블리 언어 지식이 필요합니다. C에서 다음과 같은 문 :
int myInt = 10;
어셈블리에서 다음과 같이 번역됩니다.
myInt dw 1
mov myInt,10
이것을 C ++와 같은 것과 비교하십시오.
MyClass myClass;
myClass.set_myInt(10);
결과 어셈블리 언어 코드 (MyClass () 크기에 따라 다름)는 최대 수백 개의 어셈블리 언어 라인을 추가 할 수 있습니다.
실제로 어셈블리 언어로 프로그램을 생성하지 않고 순수 C는 아마도 프로그램을 만들 수있는 "가장 얇고" "가장 엄격한"코드 일 것입니다.
편집하다
내 대답에 대한 의견을 감안할 때 나는 내 자신의 정신을 위해 테스트를 실행하기로 결정했습니다. 다음과 같은 "test.c"라는 프로그램을 만들었습니다.
#include <stdio.h>
void main()
{
int myInt=10;
printf("%d\n", myInt);
}
나는 이것을 gcc를 사용하여 어셈블리로 컴파일했습니다. 다음 명령 줄을 사용하여 컴파일했습니다.
gcc -S -O2 test.c
결과 어셈블리 언어는 다음과 같습니다.
.file "test.c"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "%d\n"
.section .text.unlikely,"ax",@progbits
.LCOLDB1:
.section .text.startup,"ax",@progbits
.LHOTB1:
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB24:
.cfi_startproc
movl $10, %edx
movl $.LC0, %esi
movl $1, %edi
xorl %eax, %eax
jmp __printf_chk
.cfi_endproc
.LFE24:
.size main, .-main
.section .text.unlikely
.LCOLDE1:
.section .text.startup
.LHOTE1:
.ident "GCC: (Ubuntu 4.9.1-16ubuntu6) 4.9.1"
.section .note.GNU-stack,"",@progbits
그런 다음 클래스를 정의하고 "test.c"와 동일한 내용을 출력하는 "test.cpp"라는 파일을 만듭니다.
#include <iostream>
using namespace std;
class MyClass {
int myVar;
public:
void set_myVar(int);
int get_myVar(void);
};
void MyClass::set_myVar(int val)
{
myVar = val;
}
int MyClass::get_myVar(void)
{
return myVar;
}
int main()
{
MyClass myClass;
myClass.set_myVar(10);
cout << myClass.get_myVar() << endl;
return 0;
}
이 명령을 사용하여 같은 방식으로 컴파일했습니다.
g++ -O2 -S test.cpp
결과 어셈블리 파일은 다음과 같습니다.
.file "test.cpp"
.section .text.unlikely,"ax",@progbits
.align 2
.LCOLDB0:
.text
.LHOTB0:
.align 2
.p2align 4,,15
.globl _ZN7MyClass9set_myVarEi
.type _ZN7MyClass9set_myVarEi, @function
_ZN7MyClass9set_myVarEi:
.LFB1047:
.cfi_startproc
movl %esi, (%rdi)
ret
.cfi_endproc
.LFE1047:
.size _ZN7MyClass9set_myVarEi, .-_ZN7MyClass9set_myVarEi
.section .text.unlikely
.LCOLDE0:
.text
.LHOTE0:
.section .text.unlikely
.align 2
.LCOLDB1:
.text
.LHOTB1:
.align 2
.p2align 4,,15
.globl _ZN7MyClass9get_myVarEv
.type _ZN7MyClass9get_myVarEv, @function
_ZN7MyClass9get_myVarEv:
.LFB1048:
.cfi_startproc
movl (%rdi), %eax
ret
.cfi_endproc
.LFE1048:
.size _ZN7MyClass9get_myVarEv, .-_ZN7MyClass9get_myVarEv
.section .text.unlikely
.LCOLDE1:
.text
.LHOTE1:
.section .text.unlikely
.LCOLDB2:
.section .text.startup,"ax",@progbits
.LHOTB2:
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB1049:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $10, %esi
movl $_ZSt4cout, %edi
call _ZNSolsEi
movq %rax, %rdi
call _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
xorl %eax, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE1049:
.size main, .-main
.section .text.unlikely
.LCOLDE2:
.section .text.startup
.LHOTE2:
.section .text.unlikely
.LCOLDB3:
.section .text.startup
.LHOTB3:
.p2align 4,,15
.type _GLOBAL__sub_I__ZN7MyClass9set_myVarEi, @function
_GLOBAL__sub_I__ZN7MyClass9set_myVarEi:
.LFB1056:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $_ZStL8__ioinit, %edi
call _ZNSt8ios_base4InitC1Ev
movl $__dso_handle, %edx
movl $_ZStL8__ioinit, %esi
movl $_ZNSt8ios_base4InitD1Ev, %edi
addq $8, %rsp
.cfi_def_cfa_offset 8
jmp __cxa_atexit
.cfi_endproc
.LFE1056:
.size _GLOBAL__sub_I__ZN7MyClass9set_myVarEi, .-_GLOBAL__sub_I__ZN7MyClass9set_myVarEi
.section .text.unlikely
.LCOLDE3:
.section .text.startup
.LHOTE3:
.section .init_array,"aw"
.align 8
.quad _GLOBAL__sub_I__ZN7MyClass9set_myVarEi
.local _ZStL8__ioinit
.comm _ZStL8__ioinit,1,1
.hidden __dso_handle
.ident "GCC: (Ubuntu 4.9.1-16ubuntu6) 4.9.1"
.section .note.GNU-stack,"",@progbits
분명히 알 수 있듯이 결과 어셈블리 파일은 C ++ 파일에서 C 파일보다 훨씬 더 큽니다. 다른 모든 것을 잘라 내고 C "main"을 C ++ "main"과 비교하더라도 많은 추가 항목이 있습니다.
MyClass myClass { 10 }
C ++ 와 같은 실제 코드 는 정확히 동일한 어셈블리로 컴파일 될 가능성이 높습니다. 최신 C ++ 컴파일러는 추상화 패널티를 제거했습니다. 결과적으로 그들은 종종 C 컴파일러를 이길 수 있습니다. 예를 들어 C의 추상화 패널티 qsort
는 실제이지만 C ++ std::sort
는 기본 최적화 후에도 추상화 패널티가 없습니다.
K & R은 대부분의 C 표현식 (기술적 의미)이 지원 라이브러리에 대한 함수 호출이 아니라 하나 또는 몇 개의 어셈블리 명령에 매핑됨을 의미합니다. 일반적인 예외는 하드웨어 div 명령어가없는 아키텍처의 정수 나누기 또는 FPU가없는 시스템의 부동 소수점입니다.
인용문이 있습니다.
C는 어셈블리 언어의 유연성과 힘을 사용자 친화적 인 어셈블리 언어와 결합합니다.
( 여기에서 찾을 수 있습니다 . "어셈블리 언어의 편리함과 표현력을 갖춘 어셈블리 언어의 속도"와 같은 다른 변형을 기억한다고 생각했습니다.)
일부 상위 수준 언어는 데이터 유형의 정확한 너비를 정의하며 모든 시스템의 구현은 동일하게 작동해야합니다. 하지만 C는 아닙니다.
x86-64에서 128 비트 정수로 작업하거나 일반적으로 임의 크기의 BigInteger로 작업하려면이를위한 함수 라이브러리가 필요합니다. 모든 CPU는 이제 음의 정수의 이진 표현으로 2의 보수를 사용하지만 C가 설계되었을 때는 그렇지 않았습니다. (이것이 2s가 아닌 시스템에서 다른 결과를 제공 할 수있는 일부 항목이 C 표준에서 기술적으로 정의되지 않은 이유입니다.)
참조 횟수 참조를 원하면 직접 수행해야합니다. 포인터가 가리키는 개체의 종류에 따라 다른 함수를 호출하는 C ++ 가상 멤버 함수를 원하는 경우 C ++ 컴파일러는call
고정 주소를 가진 명령어 합니다.
라이브러리 함수 외부에서 제공되는 유일한 문자열 작업은 문자 읽기 / 쓰기입니다. 연결 없음, 하위 문자열 없음, 검색 없음. (문자열은 nul로 끝나는 ('\0'
포인터 + 길이가 아닌 8 비트 정수의 ) 배열 되므로 부분 문자열을 얻으려면 원래 문자열에 nul을 써야합니다.)
CPU에는 때때로 문자열 검색 기능에서 사용하도록 설계된 명령어가 있지만 일반적으로 루프에서 실행되는 명령어 당 1 바이트를 처리합니다. (또는 x86 rep 접두사를 사용합니다. C가 x86에서 설계된 경우 문자열 검색 또는 비교는 라이브러리 함수 호출이 아닌 기본 작업 일 수 있습니다.)
다른 많은 답변은 예외 처리, 해시 테이블, 목록과 같이 기본적으로 지원되지 않는 것들의 예를 제공합니다. K & R의 디자인 철학은 C가 기본적으로 이러한 것을 갖지 않는 이유입니다.
프로세스의 어셈블리 언어는 일반적으로 점프 (이동), 문, 이동 문, 이진 관절염 (XOR, NAND, AND OR 등), 메모리 필드 (또는 주소)를 다룹니다. 메모리를 명령어와 데이터의 두 가지 유형으로 분류합니다. 그것은 어셈블리 언어에 관한 모든 것입니다 (어셈블리 프로그래머는 그것보다 더 많은 것이 있다고 주장 할 것이지만 일반적으로 이것으로 요약됩니다). C는이 단순함과 매우 유사합니다.
C는 대수와 산술을 조합하는 것입니다.
C는 어셈블리의 기본 (프로세서 언어)을 캡슐화합니다. "C에서 제공하는 데이터 유형과 제어 구조는 대부분의 컴퓨터에서 직접 지원되기 때문에"보다 더 사실 일 것입니다.
컴퓨터에서 직접 지원하지 않는 데이터 유형 또는 제어 구조의 예가 있습니까?
C 언어의 모든 기본 데이터 유형과 해당 작업은 루프없이 하나 또는 몇 개의 기계 언어 명령으로 구현할 수 있습니다. 이는 (실제로 모든) CPU에서 직접 지원됩니다.
널리 사용되는 여러 데이터 유형 및 해당 작업에는 수십 개의 기계 언어 명령이 필요하거나 일부 런타임 루프를 반복하거나 둘 다 필요합니다.
많은 언어에는 이러한 유형 및 해당 작업에 대한 특수 축약 구문이 있습니다. C에서 이러한 데이터 유형을 사용하려면 일반적으로 더 많은 코드를 입력해야합니다.
이러한 데이터 유형 및 작업에는 다음이 포함됩니다.
이러한 모든 작업에는 수십 개의 기계 언어 명령이 필요하거나 거의 모든 프로세서에서 일부 런타임 루프를 반복해야합니다.
수십 개의 기계 언어 명령 또는 루핑이 필요한 일부 인기있는 제어 구조는 다음과 같습니다.
C로 작성 되든 다른 언어로 작성 되든, 프로그램이 이러한 데이터 유형을 조작 할 때 CPU는 결국 해당 데이터 유형을 조작하는 데 필요한 명령을 실행해야합니다. 이러한 지침은 종종 "라이브러리"에 포함됩니다. C를 포함한 모든 프로그래밍 언어에는 모든 실행 파일에 기본적으로 포함 된 각 플랫폼에 대한 "런타임 라이브러리"가 있습니다.
컴파일러를 작성하는 대부분의 사람들은 "언어에 내장 된"모든 데이터 유형을 조작하기위한 지침을 런타임 라이브러리에 넣습니다. C는 없기 때문에 어떤 런인보다 C 런타임 라이브러리 작은 수 -하여 언어, 그들 중 누구도이 C 런타임 라이브러리에 포함되지 않습니다에 내장 된 위의 데이터 유형과 운영 및 제어 구조를 위의 내용이 더 많이 내장 된 다른 프로그래밍 언어의 시간 라이브러리.
프로그래머가 "언어에 내장"되지 않은 다른 데이터 유형을 조작하기 위해 C 또는 자신이 선택한 다른 언어로 된 프로그램을 원할 때 해당 프로그래머는 일반적으로 해당 프로그램에 추가 라이브러리를 포함하도록 컴파일러에 지시하거나 때로는 ( "종속성을 피하기 위해") 프로그램에서 이러한 작업의 또 다른 구현을 직접 작성합니다.
에 내장 된 데이터 유형은 C
무엇입니까? 그들은 같은 것들이다 int
, char
, * int
, float
, 배열 등 ... 이러한 데이터 유형이 CPU에 의해 이해된다. CPU는 배열 작업 방법, 포인터 역 참조 방법 및 포인터, 정수 및 부동 소수점 숫자에 대한 산술을 수행하는 방법을 알고 있습니다.
그러나 더 높은 수준의 프로그래밍 언어로 이동하면 추상 데이터 유형과 더 복잡한 구조를 만들었습니다. 예를 들어 C ++ 프로그래밍 언어의 방대한 내장 클래스 배열을 살펴보십시오. CPU는 클래스, 객체 또는 추상 데이터 유형을 이해하지 못하므로 C ++ 런타임은 CPU와 언어 간의 간격을 연결합니다. 다음은 대부분의 컴퓨터에서 직접 지원되지 않는 데이터 유형의 예입니다.
컴퓨터에 따라 다릅니다. C가 발명 된 PDP-11에서는 long
제대로 지원되지 않았습니다 (32 비트 작업을 전부 지원하지는 않지만 일부를 지원하는 옵션 추가 모듈이 있습니다). 이는 원래 IBM PC를 포함하여 모든 16 비트 시스템에서 다양한 수준으로 적용됩니다. 마찬가지로 32 비트 컴퓨터 나 32 비트 프로그램에서 64 비트 작업을 수행 할 때도 마찬가지지만 K & R 책 당시 C 언어에는 64 비트 작업이 전혀 없었습니다. 물론 80 년대와 90 년대에 걸쳐 많은 시스템 (386 및 486 프로세서 포함)이 있었고 심지어는 부동 소수점 산술 ( float
또는 double
)을 직접 지원하지 않는 일부 임베디드 시스템도있었습니다 .
좀 더 이국적인 예를 들어, 일부 컴퓨터 아키텍처는 "단어 지향"포인터 (메모리에서 2 바이트 또는 4 바이트 정수를 가리킴) 만 지원 하며, 추가 오프셋 필드를 추가하여 바이트 포인터 ( char *
또는 void *
)를 구현해야했습니다. 이 질문 은 그러한 시스템에 대해 자세히 설명합니다.
참조하는 "런타임 라이브러리"함수는 매뉴얼에서 볼 수있는 함수 가 아니라 기계에서 지원 하지 않는 기본 유형 작업을 구현하는 데 사용되는 현대 컴파일러의 런타임 라이브러리에서 이와 같은 함수 입니다. . K & R 자체가 언급 한 런타임 라이브러리는 The Unix Heritage Society의 웹 사이트 에서 찾을 수 있습니다. 분할을 구현하는 데 사용되는 (동일한 이름의 C 함수와는 다른) 함수를 볼 수 있습니다. PDP-11이 추가 기능으로도 지원하지 않았던 32 비트 값 과 함수에서 호출 및 반환을 관리하기 위해 스택에 레지스터를 저장하고 복원하는 (및 csv.c에서도)ldiv
csv
cret
그들은 또한 CPU의 기본 포인터 지원에 잘 매핑되지 않는 배열 의미 체계를 가진 FORTRAN과 같은 다른 현대 언어와 달리 기본 컴퓨터에서 직접 지원하지 않는 많은 데이터 유형을 지원하지 않기로 선택한 것을 언급했을 가능성이 높습니다. C의 배열. C 배열은 항상 인덱스가 0이고 모든 순위에서 항상 알려진 크기이지만 첫 번째는 배열의 인덱스 범위 또는 크기를 저장할 필요가 없으며 액세스하기 위해 런타임 라이브러리 함수를 가질 필요가 없음을 의미합니다. 컴파일러는 필요한 포인터 산술을 간단히 하드 코딩 할 수 있습니다.
이 문장은 단순히 C의 데이터와 제어 구조가 기계 지향적이라는 것을 의미합니다.
여기서 고려해야 할 두 가지 측면이 있습니다. 하나는 C 언어에 데이터 유형이 정의되는 방식에 대한 위도를 허용하는 정의 (ISO 표준)가 있다는 것입니다. 이것은 C 언어 구현이 기계에 맞게 조정 되었음을 의미합니다 . C 컴파일러의 데이터 유형은 컴파일러가 대상으로하는 컴퓨터에서 사용할 수있는 것과 일치합니다. 언어에는 이에 대한 위도가 있기 때문입니다. 기계에 36 비트와 같이 비정상적인 단어 크기가있는 경우 해당 유형 int
또는 그에 long
맞게 만들 수 있습니다. int
정확히 32 비트 라고 가정하는 프로그램 은 중단됩니다.
둘째, 이러한 이식성 문제로 인해 두 번째 효과가 있습니다. 어떤 의미에서 K & R의 진술 일종의 자기 실현 예언 이되거나 그 반대 일 수도 있습니다. 즉, 새로운 프로세서의 구현자는 C 컴파일러 지원에 대한 절실한 필요성을 알고 있으며 "모든 프로세서가 80386처럼 보인다"고 가정하는 많은 C 코드가 있음을 알고 있습니다. 아키텍처는 C를 염두에두고 설계되었습니다. C뿐만 아니라 C 이식성에 대한 일반적인 오해도 염두에두고 있습니다. 9 비트 바이트 나 일반적인 용도로 사용하는 기계를 더 이상 도입 할 수 없습니다. 유형을 가정하는 프로그램char
정확히 8 비트 너비입니다. 이식성 전문가가 작성한 일부 프로그램 만 계속 작동합니다. 합리적인 노력으로 도구 체인, 커널, 사용자 공간 및 유용한 응용 프로그램으로 전체 시스템을 결합하기에 충분하지 않을 수 있습니다. 다시 말해서, C 유형은 하드웨어가 많은 비 이식성 C 프로그램이 작성된 다른 하드웨어처럼 보이도록 만들어 졌기 때문에 하드웨어에서 사용할 수있는 것처럼 보입니다.
컴퓨터에서 직접 지원하지 않는 데이터 유형 또는 제어 구조의 예가 있습니까?
많은 기계 언어에서 직접 지원되지 않는 데이터 유형 : 다중 정밀도 정수; 연결 목록; 해시 테이블; 문자열.
대부분의 기계 언어에서 직접 지원되지 않는 제어 구조 : 일류 연속; 코 루틴 / 스레드; 발전기; 예외 처리.
이들 모두는 수많은 범용 명령어와 더 많은 기본 데이터 유형을 사용하여 생성 된 상당한 런타임 지원 코드를 필요로합니다.
C에는 일부 시스템에서 지원하지 않는 일부 표준 데이터 유형이 있습니다. C99 이후 C에는 복소수가 있습니다. 두 개의 부동 소수점 값으로 만들어지며 라이브러리 루틴과 함께 작동하도록 만들어졌습니다. 일부 기계에는 부동 소수점 단위가 전혀 없습니다.
일부 데이터 유형과 관련하여 명확하지 않습니다. 머신이 하나의 레지스터를 기본 주소로 사용하고 다른 레지스터를 스케일 변위로 사용하여 메모리 주소 지정을 지원하는 경우 배열이 직접 지원되는 데이터 유형이라는 의미입니까?
또한 부동 소수점에 대해 말하자면 IEEE 754 부동 소수점 표준화가 있습니다. C 컴파일러가 double
프로세서에서 지원하는 부동 소수점 형식과 일치하는 이유는 두 가지가 일치하도록 만들어 졌기 때문일뿐만 아니라 해당 표현에 대한 독립적 인 표준이 있기 때문입니다.
직접 지원은 프로세서의 명령어 세트에 효율적으로 매핑하는 것으로 이해해야합니다.
정수 유형에 대한 직접적인 지원은 긴 (확장 된 산술 루틴이 필요할 수 있음) 및 짧은 크기 (마스킹이 필요할 수 있음)를 제외하고는 규칙입니다.
부동 소수점 유형을 직접 지원하려면 FPU를 사용할 수 있어야합니다.
비트 필드에 대한 직접적인 지원은 예외적입니다.
구조체와 배열에는 주소 계산이 필요하며 어느 정도 직접 지원됩니다.
포인터는 항상 간접 주소 지정을 통해 직접 지원됩니다.
goto / if / while / for / do는 무조건 / 조건부 분기에서 직접 지원됩니다.
점프 테이블이 적용될 때 스위치를 직접 지원할 수 있습니다.
함수 호출은 스택 기능을 통해 직접 지원됩니다.