이 코드는 가변 인수 함수에 전달되는 값은 float
같이 double
변환이 발생 .. double
에 float
하고 일부 정수형 변환하고자한다.
FLT_EVAL_METHOD
의 설정을 확인하십시오. 값이 1 또는 2로 추정됩니다 (최소 1 개의 컴파일러가있는 OP 보고서 2
). 따라서 컴파일러는 float
"... 범위와 정밀도에 대한 작업 및 상수"를 float
보다 크게 계산할 수 있습니다.
컴파일러는 (float)x
에 직접 최적화되어 int
에서 double
까지 계산됩니다. 이것은 런타임 동안의 성능 향상입니다. 성능이 여기에 문제가되지 않습니다으로
(float)2147483647
컴파일 시간 캐스트 및 double
정확성 float
에 int
에 최적화 된 컴파일러입니다.
[Edit2가] C11 사양은 "할당 및 캐스트를 제외하고 ..."의 추가와 C99 사양보다 더 구체적이다 재미있다. 이는 C99 컴파일러가 float
을 거치지 않고 int
에서 double
으로 직접 변환을 허용하고 C11이 캐스트를 건너 뛰는 것을 분명히 허용하지 않도록 수정했다는 것을 의미합니다.
공식적으로이 동작을 제외하면 현대 작성자가 OP를 할 수있는 것처럼 오래된 수식을 사용해서는 안됩니다. 따라서 C11 표준에 의한 버그 일 수 있습니다. 다른 C99 또는 C89 사양이 다른 것으로 밝혀지지 않는 한, 이는 허용 가능한 컴파일러 동작 인 것으로 보입니다.
는 [편집]이 심지어 비 - 제로 FLT_EVAL_METHOD
와 @Keith 톰슨 @tmyklebu, @ 매트 McNabb 컴파일러에 의해 함께 코멘트를 복용 2147483648.0...
을 생성 할 것으로 예상한다. 따라서 컴파일러 최적화 플래그가 명시 적으로 올바른 동작을 오버라이드하거나 컴파일러에 모서리 버그가 있습니다.
C99dr §5.2.4.2.2 8 플로팅 피연산자 연산 값과 일반적인 산술 변환 및 부동 상수 값은 그 대상 범위보다 정밀도 요구 될 수있는 형식으로 평가 유형별. 평가 형식의 사용 FLT_EVAL_METHOD 구현 정의 값을 특징으로한다 :
-1 확정 할;
0은 유형의 범위와 정밀도에 대한 모든 연산과 상수를 평가합니다.
1 범위 및 long double
type`의 정밀도 long double
연산 상수를 평가 및 조작 범위 및 double
타입의 정밀도 및 유형 float
double
의 정수를 평가;
2는 모든 연산과 상수를 long double
유형의 범위와 정밀도로 평가합니다.
C11dr는 (모든 여분의 범위와 정밀도를 제거) 할당 및 캐스트를 제외하고 §5.2.4.2.2 9, 부동 피연산자 운영자에 의해 산출 된 값 및 일반 산술 변환과의 주제 값 부동 소수점 형은 범위와 정밀도가 형식에 필요한 것보다 클 수있는 형식으로 평가됩니다. 평가 형식의 사용 구현 정의 값 FLT_EVAL_METHOD 특징
-1 (동일 C99 등)
0 (동일 C99 등)
1 (동일 C99 등)
2 (C99과 동일)
컴파일러와 비슷하게 보입니다. 이데 폰은 동일한 수를 제공합니다. MinGW GCC 4.5.2는 자신이하는 것과 동일한 결과를 제공합니다. –
나는 이것이 컴파일러에 의존한다고 생각한다. gcc 4.8.2의 경우 두 경우 모두 2147483648.000000이 표시됩니다. – rocker
최적화 버그. 두 컴파일러, mingw/gcc-3.4.2 및 vs6에서 동일한 출력입니까? BTW : 둘 다 ** 오래된 **입니다. – Deduplicator