2012-02-02 1 views
17

오늘 오전 12시 30 분에 템플릿 코드에서 BOOST_STATIC_ASSERT을 사용하여 잘못된 유형의 참조를 작성하지 않도록했습니다. 분명히 오류 메시지 일 수 있습니다.C++은 const double을 처리하고 int를 참조하는 방식은 무엇입니까?

#include <iostream> 

int main() 
{ 
    int x = 5; 
    const double& y = x; 
    std::cout << y << std::endl; 

    return 0; 
} 

: 나는 당신이 const를 더블 &이 int로 참조 할 때조차 불평하지 않는 GCC를 발견하는 충격을 받았다 대체 컴파일러 오류 살펴보고 정적 어설 제거하려고하지만 경우 컴파일하고 경고하지 않습니다.

$ g++ ~/stuff/badRef.cpp -Wall -Wextra -pedantic 
$ a.out 
5 

여기에 무슨 일이 일어나고있는가요? 이것은 정의되지 않은 동작입니까? 그렇다면 왜 gcc는 불평하지 않습니까? 내 컴퓨터에서 int는 4 바이트이고 double은 8입니다. 즉, double을 인쇄 할 때 그 주소에서 8 바이트를 double로 해석하고 인쇄해야한다는 것을 의미합니다. 실제로는 그 위치에 4 ​​바이트의 int가 있습니다.

매우 혼란 스럽습니다. 도움!

+0

어떤 버전의 GCC입니까? –

+0

버전 4.3.3입니다. – voltrevo

+0

'const double & y = x;'뒤에'x = 42;'를 추가하면 어떻게됩니까? 첫눈에 호기심이 있거나 예기치 못한 경우 일 수 있습니다. – moala

답변

22

const double& y = x;static_cast<double>(x) 값의 임시 double을 만든 다음 임시로 y에 바인딩합니다. 임시의 수명은 y의 수명과 일치하도록 연장됩니다.

이것은 완전히 합법적 인 C++ (03 및 11)이므로 경고/오류가 없습니다.

+0

굉장합니다. x를 증가시키고 y를 인쇄 할 때 어떤 일이 일어나는지 보면서 답을하기 직전에 실제로 알아 냈습니다. 그것은 변하지 않았기 때문에 나는 생각했다. "당연히! 그것은 일시적으로 구속된다!". 또한, gcc는 -std = C++ 98도 허용하므로 유효한 C++ 98이라고 생각합니다. – voltrevo

+0

@ Mozza314 : "* 유효한 C++ 98이라고 생각합니까? *"예; 나는 그 특정 표준의 사본을 가지고 있지는 않지만, C++ 03에 추가 된 것들 중 하나가 아니라는 것은 확실하다.하지만'-std = C++ 98'은 실제로 C++ 98 규칙이 아닌 C++ 03 규칙을 적용하고 인수 이름은 무시하지 않습니다. – ildjarn

+0

나는 그것을 얻지 못한다 ... 왜'const double' 대신에 임시로 바인딩 할 때'const double &'을 할 것인가? – Mehrdad

2

const T& 임시로 결합 할 수 있으므로 xdouble로 전환되고 있으며 복사가 y에 바인딩됩니다. 확인하면 &x != &y이 표시됩니다. 이 동작의 이유는 리터럴을 const 참조로 매개 변수를 사용하는 함수에 전달할 수있게하기 위해서입니다.

+0

음, "복사본이 저장되지 않았습니다", y는 변환으로 인해 임시로 바인드됩니다. 왜냐하면 const 좌측 값 참조이기 때문입니다. –

+0

@CatPlusPlus : "에 저장"으로 바뀌 었습니다. 명확히 밝혀지지 않았다면, 적어도 pedantically 맞습니다. : P –

11

잘 정의되어 있고 합법적입니다. y은 임시를 나타냅니다. 또한 참조을에서 const되지 않은 경우이 유효 C++ 이 아니라고

void foo(const int& p); 
foo(3.14); 

참고 :이 매개 변수를 전달하는 경우도 고려한다. VS 6이 잘못되어 임시 바인딩을 변경할 수 있습니다. 이것은 const 참조에만 적용됩니다.

1

이것은 포인터와 참조가 동일하다고 생각하는 사람들에게 좋은 예입니다.

double const*const y2 = &x; 

gives 
bad.cpp:7:30: error: cannot convert ‘int*’ to ‘const double* const’ in initialization 

다른 게시물에 설명 된 이유가 설명되어 있습니다.

관련 문제