2010-07-13 4 views
4

"int"맛 (부호없는 정수, long int, long long int)에 대해서는 다음과 같은 의심의 여지가 있습니다."int"맛의 조작에 관한 의심

우리가 어떤 작업을 수행 할 때 (*, /, +, -) 32 비트 시스템과 64 비트 시스템에서 INT와 맛 사이를 (long int와 말을 할 수 있습니다) 는 암시 적 타입 캐스트는 "INT"

에 대한 일입니다 예 : -

int x; long long int y = 2000;

x = y; (더 높은 것은 하나의 데이터 잘림이 일어날 수 있습니다.) 컴파일러가 이에 대한 경고를하기를 기대합니다. 그러나 나는 그러한 경고를 얻지 못하고 있습니다. 여기서 "x"에 대한 암시 적 타입 변환이 발생 했습니까? -Wall 옵션과 함께 gcc를 사용하고 있습니다. 동작이 32 비트 및 64 비트 용으로 변경됩니까? 당신이 걱정하는 경우

감사 Arpit

+0

아래에 정말 좋은 답변이 있습니다. 아마도 올바른 것으로 표시 할 수 있습니까? – alecco

답변

7

-Wall은 가능한 모든 경고를 활성화하지 않습니다. -Wextra은 다른 경고를 사용합니다. 어쨌든, 당신이하는 일은 완벽하게 "합법적 인"연산이며 컴파일러는 컴파일 타임에 "잘라 버릴"수있는 데이텀의 값을 항상 알 수 없으므로 경고하지 않습니다. 프로그래머는 이미 알고 있어야합니다. "큰"정수인 이 "작은"정수에 맞지 않으므로 일반적으로 프로그래머에게 달려 있습니다. 프로그램이이 사실을 모른 채로 작성되었다고 생각하면 -Wconversion을 추가하십시오.

+0

예, 다른 것들 중에서도 -Wconversion은 암시 적으로 더 큰 유형을 더 작은 유형으로 변환 할 때 알려줍니다. gcc의 Apple 지사에는'-Wshorten-64-to-32'도 있습니다. – JeremyP

+0

+1 - W 변환. – Dummy00001

2

, 당신은 <stdint.h> 및 사용에 정의 된 길이와 유형, 16 비트 부호없는 정수에 대한 같은 uint16_t를 포함 할 수 있습니다.

1

http://gcc.gnu.org/ml/gcc-help/2003-06/msg00086.html 참조 - 코드는 C/C++에서 완벽하게 유효합니다.

정적 분석 도구 (스파 스, llvm 등)를보고이 유형의 잘림을 검사 할 수 있습니다.

+0

음, GCC 사람들은 때때로 도움이되지 않습니다 .../나 gcc 및 엄격한 앨리어싱 규칙에 대해 생각합니다./나는 떨린다. – Dummy00001

3

명시 적 형식 캐스팅 연산자가없는 캐스트는 C에서는 완벽하게 사용할 수 있지만 정의되지 않은 동작이있을 수 있습니다. 귀하의 경우 이 서명되었으므로 int 범위를 벗어나는 값을 저장하려고하면 프로그램에 정의되지 않은 동작이 발생합니다. 한편, xunsigned x;으로 선언 된 경우 동작은 잘 정의되어 있습니다. 캐스트는 환원 계수 모듈 UINT_MAX+1입니다.

다른 유형의 정수 사이에서 산술을 수행 할 때 '보다 작음'유형은 산술에 앞서 '더 큰'유형으로 승격됩니다. 컴파일러는 결과에 영향을 미치지 않으면 물론이 프로모션을 최적화 할 수 있으므로 전체 64 비트 결과를 얻기 위해 곱하기 전에 32 비트 정수를 64 비트로 변환하는 것과 같은 관용구가됩니다. 프로모션은 다소 혼란스러워지며 서명 된 값과 부호없는 값이 섞여있을 때 예기치 않은 결과가 발생할 수 있습니다. 비공식적으로 설명하기가 어렵 기 때문에 알아두면주의해야합니다.

+0

좋은 답변이지만 "암시 적 캐스팅"을 피하는 경향이 있습니다. 정의에 의한 캐스트는 명시 적입니다. 변환은 내재적이거나 명시 적입니다. –

+1

새로운 문구가 더 좋습니까? –

+0

@R : 확실하지 않습니다. 여기에있는 문제는 대답에 적혀 있듯이 관련 유형이며 캐스팅과 변환이 전혀 적용되지 않습니다. 캐스트 또는 변환이 있는지 여부에 관계없이 정의되지 않은 동일한 동작이 존재합니다. 주어진'long x = 200000; int i = x; int j = (int) x;','i'와'j'에 대한 할당은 모두 잠재적 인 문제입니다. –

2

코드가 완벽하게 유효합니다 (이미 다른 사람들이 말한대로). 대부분의 경우 휴대용 방식으로 프로그래밍하려는 경우 맨손 C 유형 int, long 또는 unsigned int을 사용하지 말고 유형으로 수행하려는 작업을 조금 더 잘 나타내야합니다.

예 : 배열의 인덱스는 항상 size_t입니다. 32 또는 64 비트 시스템에 있는지 여부에 관계없이 올바른 유형입니다.또는 플랫폼 상 최대 너비의 정수를 가져 오려면 착륙하는 경우 intmax_t 또는 uintmax_t을 사용하십시오.