2014-10-20 10 views
0

다음 스 니펫의 동작은 정의되지 않았다고 가정합니다. 그러나 저는 지금 올바르게 이해하고 싶습니다. 의 우리가이 코드가 있다고 가정 해 봅시다 :const char * int로 변환 하시겠습니까?

#include <iostream> 

int main() 
{ 
    std::cout << "mamut" - 8 << std::endl; 
    return 0; 
} 

을 그래서 생각이는 않습니다 (숯불 *) ((INT) (CONST의 char *) - (INT)),이 후 출력이 꽤 이상하다하지만, 나는 그것이 진짜 의미가 있다고 기대하지 않는다. 그래서 내 질문에 대한 char * 및 int - 사이에 캐스팅에 대한 정의되지 않은, 또는 거기에 몇 가지 논리가 뒤에?

편집 : 나 그냥이 추가하자 :

#include <iostream> 

int main() 
{ 
    const char* a = "mamut"; 
    int b = int(a); 
    std::cout << b << std::endl; 
    std::cout << &a <<std::endl; 
    // seems b!= &a 
    for(int i = 0; i<100;i++) 
    { 
     std::cout<<(const char*)((int)a - i)<<std::endl; 
    } 

    return 0; 
} 

출력을 내가 충분히 커질 나에게 등 _Jv_RegisterClasses 그냥 레코드에 대한 같은 것을 제공 후 :

std::cout << a - i << std::endl; 

가 생산을 동일한 결과 :

std::cout<<(const char*)((int)a - i)<<std::endl; 
+0

는하지만 때문에 당신이 생각하는 이유의 정의되지 않은 동작입니다. Google 포인터 연산. –

+0

'const char *'는'8'을 뺄 때'int'로 변환됩니다. 가정이 잘못되었습니다. – user2079303

+0

가정이 틀린 이유는 무엇입니까?char * + char *에 대해 +가 정의되지 않았으므로 char *을 추가 할 수 없다는 의미입니다. – lightxbulb

답변

5

캐스트가 없으므로 문자 리터럴 "mamut"에서 8 바이트를 뺀 주소에 문자열을 출력하려고한다는 것을 cout에게 알려주는 것입니다. 당신은 포인터 연산을하고 있습니다. cout은 그 주소에 어떤 일이 생기면 인쇄 할 것이고 &이 충돌 할 수 있습니다. 범위를 벗어나는 배열에 액세스하면 정의되지 않은 동작이 발생하기 때문입니다. 반드시 주소와 동일한 정확한 수에 포함되지 않는다 int에 주소 변환 : 연산에 의해 수정 대하여

EDIT

. 주소가 반드시 int에 들어가는 것은 아니며 그 중 int은 서명 된 유형이며 서명 된 유형에 주소를 저장하는 것은 의미가 없습니다.

손실없이 포인터에서 정수로 변환하려면 stdint.h에서 uintptr_t을 사용해야합니다.

모든 포인터 유형이 정수 유형으로 변환 할 수 있습니다

는 C 표준 6.3.2.3 (나는 C++이 경우 동일하다 생각)을 인용합니다. 앞서 지정된 을 제외하고 결과는 구현에 따라 정의됩니다. 결과를 정수 유형으로 나타낼 수없는 경우 동작은 입니다. 결과는 정수 유형의 값 범위 일 필요는 없습니다.

+0

문제는 (int)가 나에게 주소를주지 않는다는 것입니다. 기본적으로 &! = (int) a. 처음부터 내 질문은 (int) 무엇을 나에게 줄 것인가였다. – lightxbulb

+0

@lightxbulb 나는 당신의 질문에 대한 코멘트에서 이미 대답했다. 이 답변에 대한 설명을 완성을 위해 추가하겠습니다. – Lundin

+0

그래서 그것은 정의되지 않은 동작이며 캐스팅 (int) (const char *) 실제로 그 뒤에 로직이 있습니까? 캐스트가 논리적 인 결과를 가져 오지 않는다는 뜻인가요? – lightxbulb

1

캐스팅 진행이 없습니다. "mamut"은 문자에 대한 포인터이고 - 8은 포인터 연산을 수행합니다. 당신은 그것이 정의되지 않은 행동이라는 것이 옳다. 그래서 의미 론적 행동이 포인터 산술이라 할지라도, 런타임 행동은 그대로 될 수있다.

+0

그러면 주소가 (int) (const char *)에서 얻은 숫자와 일치하지 않는 이유는 무엇입니까? – lightxbulb

+0

무슨 뜻인지 이해가 안됩니다. 질문을 정확하게 설명하는 코드를 게시하십시오. 그러나 저는 UB가 말 그대로 무엇인가 일어날 수 있다는 것을 강조하려고 노력하고 있습니다. UB를 통해 설명 할 필요는 없습니다. 코드에서 UB를 제거하면 더 이상 파고들 수 있습니다. – tenfour

0

당신은 "mamut"마이너스 총 8+5 = 13 문자에 null 종결 즉까지 8 바이트의 주소에서 시작하는 문자열을 인쇄는