IT이야기

플랫폼에서 "긴"과 "int"의 크기가 동일하다면 - "긴"과 "int"는 어떤 면에서 다른가?

cyworld 2022. 5. 26. 23:07
반응형

플랫폼에서 "긴"과 "int"의 크기가 동일하다면 - "긴"과 "int"는 어떤 면에서 다른가?

의 표현일 경우long int그리고 aint플랫폼에서도 똑같아, 그들은 완전히 같은가?C 표준에 따라 플랫폼에서 어떤 방식으로든 유형이 다르게 동작하는가?

예를 들어, 이것은 항상 효과가 있는가?

int int_var;
long long_var;

void long_bar(long *l);
void int_bar(int *i);

void foo() 
{
    long_bar(&int_var); /* Always OK? */
    int_bar(&long_var);
}

나는 같은 질문이 짧은 질문이나 짧은 질문에도 적용된다고 생각한다. 만약 그것들이 같은 표현이라면 말이다.

그 문제는 어떻게 정의해야 하는지를 토론할 때 일어났다.int32_t- stdint.h가 없는 내장형 C89 컴파일러에 대한 typeef와 같은 형식.int또는long그리고 만약 그게 문제가 된다면.

이러한 유형은 다음과 같은 간단한 예를 통해 확인할 수 있는 호환성이 없는 유형이다.

int* iptr;
long* lptr = iptr; // compiler error here

그래서 이러한 유형의 포인터를 다룰 때 주로 문제가 된다.마찬가지로, 이 코드를 정의되지 않은 동작으로 만드는 "엄격한 앨리어싱 규칙"이 있다.

int i;
long* lptr = (long*)&i;
*lptr = ...;  // undefined behavior

또 다른 미묘한 문제는 암묵적인 승진이다.혹시라도some_int + some_long그 표현식의 결과 유형은long또는 두 매개 변수가 서명되지 않은 경우unsigned long. 이것은 일반적인 산술 변환을 통한 정수 승급 때문이다. Implicit type 프로모션 규칙을 참조하십시오.대부분의 경우 중요하지 않지만 이런 코드는 실패할 것이다._Generic(some_int + some_long, int: stuff() )없기 때문에long표현상의 절

일반적으로 유형 간에 값을 할당할 때 문제가 발생하지 않아야 한다.의 경우uint32_t어떤 종류에 해당하는지는 중요하지 않다. 왜냐하면 치료해야 하기 때문이다.uint32_t어쨌든 별개의 유형으로.나는 고를 것이다.long다음과 같은 경우 소형 마이크로컨트롤러와의 호환성을 위해typedef unsigned int uint32_t;부서질 거야 (그리고 분명히typedef signed long int32_t;(서명된 등가물의 경우)

유형long그리고int계급이 다르다서열.long종류보다 높다.int. 따라서 이항식에서는 이항식(binary format)의 객체가 사용되며,long그리고 타입의 물체int마지막은 항상 유형으로 변환된다.long.

다음 코드 스니펫을 비교하십시오.

int x = 0;
unsigned int y = 0;

표현 유형x + y이다unsigned int.

long x = 0;
unsigned int y = 0;

표현 유형x + y이다unsigned long(일반적인 산술 변환으로 인해)sizeof( int )와 같다sizeof( long).

이것은 기능 과부하가 허용되는 C보다 C++에서 매우 중요하다.

C에서는 예를 들어 I/O 기능을 사용할 때 이를 고려해야 한다.printf올바른 변환 지정자를 지정하십시오.

심지어 다음이 있는 플랫폼에서도long그리고int이 기준서는 동일한 표현을 가지고 있으므로, 컴파일러는 가치의 저장행위의 가능성을 의도적으로 보지 못하게 할 수 있다.long*의 가치에 영향을 미칠 수 있다int*또는 그 반대의 경우도 마찬가지야.다음과 같은 경우:

#include <stdint.h>

void store_to_int32(void *p, int index)
{
    ((int32_t*)p)[index] = 2;
}
int array1[10];
int test1(int index)
{
    array1[0] = 1;
    store_to_int32(array1, index);
    return array1[0];
}
long array2[10];
long test2(int index)
{
    array2[0] = 1;
    store_to_int32(array2, index);
    return array2[0];
}

는 32★ ARM의 gcc를 이다.int32_t와 로서.long그리고 의 주소를 에 전달할 가능성을 무시한다.array1store_to_int32그 배열의 첫 번째 요소가 쓰여지게 할 수 있고 32비트 버전의 clang은int32_t와 로서.int그리고 주소의 통과 가능성을 무시한다.array2store_to_int32배열의 첫 번째 요소가 기록될 수 있어

확실히, 이 기준서의 그 어떤 것도 컴파일러들이 그러한 방식으로 행동하는 것을 금지하지 않을 것이지만, 나는 이 기준서가 그러한 맹목성을 금지하지 않는 것은 "어떤 것이 더 멍청해질수록, 그것을 금지할 필요를 줄여야 한다"는 원칙에서 기인한다고 생각한다.

참조URL: https://stackoverflow.com/questions/66850401/if-the-size-of-long-and-int-are-the-same-on-a-platform-are-long-and-int

반응형