source

C와 C++의 산술 연산 전에 단락을 int로 변환해야 하는 이유는 무엇입니까?

manysource 2023. 1. 17. 21:20

C와 C++의 산술 연산 전에 단락을 int로 변환해야 하는 이유는 무엇입니까?

이 질문에서 얻은 답변에 따르면 C++는 이 변환 요건을 계승한 것으로 보입니다.shortintC에서 산술 연산을 수행할 때.애초에 왜 이것이 C에 도입되었는지 당신의 머리를 긁어봐도 될까요?이러한 작업을 그냥 다음과 같이 수행하는 것은 어떨까요?short

를 들어 (댓글에 있는 dyp의 제안에서 인용):

short s = 1, t = 2 ;
auto  x = s + t ;

xint 타입이 됩니다.

섹션의 국제표준(프로그래밍 언어)의 이론적 근거를 살펴보면,6.3.1.8 통상적인 산술 변환에는 다음과 같이 적혀 있습니다(내 것은 앞으로 강조).

이러한 전환에 대한 이 기준서의 규칙은 K&R의 규정을 약간 수정한 것이다.명시적 라이선스가 추가되어 절대적으로 필요한 것보다 "와이어" 타입의 계산을 수행할 수 있게 되었습니다.이것에 의해, 정답의 빈도가 높아지는 것은 말할 것도 없고, 보다 작고 고속의 코드가 생성되는 경우가 있기 때문입니다.계산은 같은 최종 결과가 얻어지는 한 규칙에 의해 "좁은" 유형으로 실행할 수도 있습니다.명시적 캐스팅을 사용하여 원하는 유형의 값을 얻을 수 있습니다.

초안 C99 표준의 섹션 6.3.1.8은 예를 들어 섹션 6.5.6의 산술식 피연산자에 적용되는 일반 산술 변환을 다룬다. 가산 연산자는 다음과 같이 말한다.

양쪽 오퍼랜드가 산술 타입을 가지는 경우, 통상적인 산술 변환이 실행됩니다.

섹션 6.5.5 곱셈 연산자에서도 유사한 텍스트를 찾을 수 있다.짧은 오퍼랜드의 경우 먼저 섹션 6.3.1.1 부울, 문자 다음과 같은 정수부터 정수 프로모션이 적용됩니다.

int가 원래 유형의 모든 값을 나타낼 수 있는 경우 값은 int로 변환됩니다.그렇지 않은 경우 부호 없는 int로 변환됩니다.이를 정수 48)프로모션이라고 합니다.다른 모든 유형은 정수 프로모션에 의해 변경되지 않습니다.

6.3.1.1사실 정수 프로모션에 관한 국제표준(International Standard: Programming Languages)의 C가 더 흥미롭습니다. B/c를 선택적으로 인용하겠습니다. 완전히 인용하기에는 너무 깁니다.

구현은 서명되지 않은 보존과 가치 보존으로 특징지을 수 있는 두 가지 주요 진영으로 구분됩니다.

[...]

서명되지 않은 보존 방식에서는 두 개의 작은 서명되지 않은 유형을 서명되지 않은 int로 승격해야 합니다.이는 단순한 규칙이며 실행 환경에 독립적인 유형을 생성합니다.

보존 접근법에서는 해당 유형이 원래 유형의 모든 값을 적절하게 나타낼 수 있는 경우 해당 유형을 서명되지 않은 int로 승격하고, 그렇지 않은 경우 해당 유형을 서명되지 않은 int로 승격해야 합니다.따라서 실행 환경이 int보다 작은 값으로 short를 나타내면 unsigned short는 int가 되고 그렇지 않으면 unsigned int가 됩니다.

부호 없는 타입과 부호 있는 타입의 사이에 암묵적인 변환의 동작이 일관되지 않는 을 알 수 있듯이, 경우에 따라서는 예기치 않은 결과가 발생할 수 있습니다.이러한 예는 훨씬 더 많습니다.단, 대부분의 경우 조작은 예상대로 동작합니다.

short ★★★★★★★★★★★★★★★★★」char타입은 표준적인 종류의 "스토리지 타입"으로 간주됩니다.즉, 공간을 절약하기 위해 사용할 수 있지만 CPU의 사이즈가 "비자연적"이기 때문에 속도를 높일 수 없습니다.

좋은 없는 없는 알 수 .unsigned char -> int g의 경우 내부 코드입니다.

void incbuf(unsigned char *buf, int size) {
    for (int i=0; i<size; i++) {
        buf[i] = buf[i] + 1;
    }
}

그냥

.L3:
    addb    $1, (%rdi,%rax)
    addq    $1, %rax
    cmpl    %eax, %esi
    jg  .L3
.L1:

서 부호 문자 지시 없는 문자 추가 지시)를볼 수 있습니다.addb되고 있습니다가 사용됩니다.

짧은 int 사이에 계산을 수행하고 결과를 짧은 int에 저장하는 경우에도 마찬가지입니다.

이 링크된 질문에는 CPU는 전혀 해당되지 않는다는 내용이 포함되어 있는 것 같습니다.32비트 CPU에는 32비트 레지스터에 대한 네이티브 산술 연산이 설정되어 있습니다.크기로 하며, 에서는 작은 에 복사하는16비트 의 확장 인 것처럼 이러한 동작에서는, 작은 값을 네이티브 사이즈의 레지스터에 카피하는 것은 저비용입니다(x86 아키텍처에서는 32비트 레지스터는 16비트 레지스터의 확장 버전인 것처럼 명명됩니다).eax로.ax,ebx로.bx, 등). x86 정수 명령 참조).

일부 극히 일반적인 연산, 특히 벡터/플로트 산술의 경우 다른 레지스터 유형 또는 크기로 동작하는 특수 명령이 있을 수 있습니다.예를 들어, (최대) 16비트의 제로 패딩은 퍼포먼스 비용이 거의 들지 않습니다.특화된 명령어를 추가하는 것은 다이에 시간과 공간을 들일 가치가 없을 것입니다(왜 그런지 정말 물리적으로 알고 싶다면, 실제 공간을 차지할지 모르겠지만, 훨씬 복잡해집니다).

코드가 실행되는 물리적 프로세서 아키텍처의 제한인 만큼 언어의 기능은 아닙니다.intC의 typer는 보통 표준 CPU 레지스터 크기입니다.실리콘이 많을수록 더 많은 공간과 전력을 차지하기 때문에 대부분의 경우 "자연 크기" 데이터 유형에 대해서만 계산이 가능합니다.이는 보편적으로 해당되는 것은 아니지만 대부분의 아키텍처에는 여전히 이러한 제한이 있습니다.즉, 2개의 8비트 숫자를 추가할 때 프로세서에서 실제로 실행되는 것은 32비트 연산과 그 다음 단순한 비트 마스크 또는 다른 적절한 유형의 변환입니다.

언급URL : https://stackoverflow.com/questions/24371868/why-must-a-short-be-converted-to-an-int-before-arithmetic-operations-in-c-and-c