플랫폼에서 "긴"과 "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
그리고 의 주소를 에 전달할 가능성을 무시한다.array1
로store_to_int32
그 배열의 첫 번째 요소가 쓰여지게 할 수 있고 32비트 버전의 clang은int32_t
와 로서.int
그리고 주소의 통과 가능성을 무시한다.array2
로store_to_int32
배열의 첫 번째 요소가 기록될 수 있어
확실히, 이 기준서의 그 어떤 것도 컴파일러들이 그러한 방식으로 행동하는 것을 금지하지 않을 것이지만, 나는 이 기준서가 그러한 맹목성을 금지하지 않는 것은 "어떤 것이 더 멍청해질수록, 그것을 금지할 필요를 줄여야 한다"는 원칙에서 기인한다고 생각한다.
'IT이야기' 카테고리의 다른 글
Java: Unix 타임스탬프의 날짜 (0) | 2022.05.26 |
---|---|
VueJS 두 매개 변수를 Vuex 작업에 전달하는 방법 (0) | 2022.05.26 |
명시적으로 선언되지 않은 Vue 소품 (0) | 2022.05.26 |
vuex 알 수 없는 작업 유형: showRegisterLogin/show (0) | 2022.05.26 |
C에서 실행 파일의 위치를 찾으려면 어떻게 해야 하는가? (0) | 2022.05.25 |