2016-06-15 2 views
1

의 유형을 내 머리말을 붙일 수 없습니다. 에 의해 , 여기 내 말은 왼쪽 값 또는 ? 이 단항 것으로 보인다 위의 코드에서, p의 (증가 객체를 반환 접두사 대응과는 달리)에 unincremented 값을 반환 ++ 후위 이후 지금C++의 Dereference 연산자

int i = 1, *p = &i; 
cout << *p++; // Prints 1, so far so good. 

:

는 다음 코드를 고려 *은 유일한 피연산자로 rvalue를 허용합니다. 그러나,

cout << *i; // error: invalid type argument of unary ‘*’ (have ‘int’) 

좋아요는 어쩌면 i의 값은 유효한 메모리 주소를 나타내지 않습니다.

unsigned long add = p; // error: invalid conversion from ‘int*’ to ‘long unsigned int’ [-fpermissive] 
cout << *add;   // error: invalid type argument of unary ‘*’ (have ‘int’) 

이 또한 나를 나의 다음 질문으로 제공 : 이제 * 단항 유효한 메모리 위치를 나타내는를 rvalue 작업을 할 수 있는지 확인하기 위해, 나는 이런 식으로 뭔가를 시도했다. unsigned long의 크기를 64 비트라고 가정하면 (작업중인 시스템의 경우), p (64 비트 메모리 주소가 될 수 있음)에 복사 할 수없는 이유는 무엇입니까? add에? 또는 다른 말로하면, 비 포인터 유형의 변수에 메모리 주소를 저장하는 방법이 있습니까 (메모리 주소가 결국 값이기 때문에 가능하지 않다면 놀랄 것입니다).

감사

+2

'*'는 포인터에서만 사용할 수 있습니다. 'i'와'add'는 포인터가 아닌 정수이므로'* i'와'* add' 코드는 실패합니다; 가치 범주와 관련이 없습니다. –

+0

비트 수를 생각하지 마십시오. 'int'와'double'은 둘 다 123bits 길이가 될 수 있습니다. 그러나 다른 유형입니다. 'int'와'unsigned int'는 각각 62 비트가 될 수 있지만 타입이 다릅니다. 포인터와 정수는 둘 다 같은 수의 비트를 가질지라도 서로 다른 유형입니다. 대다수의 경우 포인터를 정수로 또는 그 반대로 변환 할 필요가 없습니다. 이것은 끔찍한 코드 냄새입니다. – chi

답변

3

내장 된 참조 연산자는 가 포인터 타입의 수있는 prvalue을합니다. 피연산자가 glvalue 인 경우 역 참조 전에 lvalue-to-rvalue 변환됩니다.

데이터 포인터 유형과 동등한 크기의 정수 유형간에 변환하려는 경우 reinterpret_cast을 사용하여 원하는대로 지정할 수 있습니다. 이것은 오류를 방지하기위한 것입니다. int에 대한 포인터를 역 참조하는 것을 잊었습니다.

+0

내장 된 역 참조 연산자가 prvalue를 사용한다는 표준이 명시되어 있습니까? 5.3.1의 첫 번째 단락에서는 함수에 대한 포인터 또는 포인터에 대한 포인터를 사용한다고 설명합니다. 값 범주를 지정하지 않습니다. xvalue에서도 사용할 수있었습니다 : http://ideone.com/GT2Qm9. – PcAF

+1

@PcAF [conv.lval]/1을 참조하십시오. prvalue가 필요한 컨텍스트에서 (예 :'*'의 피연산자), glvalue가 prvalue로 변환 될 수 있습니다. –

+0

xvalue에 관해서는 저의 lvalue-to-rvalue 변환이 glvalues가 아닌 lvalues에 적용됩니다. 그러나 여전히 질문이 남아 있습니다. 어떤 문서를 읽고 있습니까? [n4594] (http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/n4594.pdf) [conv.lval]/1에는 그러한 문장이 없습니다. – PcAF

0

명시 적 캐스트 (reinterpret_cast 또는 C 스타일 캐스트)없이 포인터 유형을 비 포인터 유형으로 변환 할 수 없습니다. 또는 클래스에는 암시 적 변환 연산자가 있어야합니다. int 또는 long이 포인터 유형에 맞다고 가정하면 이는 틀리며 위험한 가정입니다. 이러한 위험을 감수한다면 포인터를 비 포인터 타입으로 저장할 수 있습니다 :

int main() 
{  
    int a, b; 
    a = 10; 
    b = (int)&a; 

    a = 40; 
    cout << *(int*)b << endl; 

    *(reinterpret_cast<int*>(b)) = 160; 
    cout << a << endl; 
}