이것은 w가 실제로 변수가 아니고 컴파일 된 코드에 실제로 존재하지 않도록 코드가 최적화되었을 수 있기 때문에 const 캐스트가 정의되지 않은 경우 중 하나입니다.
다음을 시도하십시오.
const volatile int w = 10;
int &wr = const_cast <int &> (w);
wr = 20;
std::cout << w << std::endl;
어쨌든, 나는 그렇게 const_cast를 남용하는 것을 권하지 않을 것입니다.
-------------------위 예제의 코드는 다음 어셈블러로 변환됩니다.
movl $10, 28(%esp) //const int i = 10;
leal 28(%esp), %eax //int* wp = const_cast <int*>(&i);
movl %eax, 24(%esp) //store the pointer on the stack
movl 24(%esp), %eax //place the value of wp in eax
movl $20, (%eax) //*wp = 20; - so all good until here
movl $10, 4(%esp) //place constant value 10 onto the the stack for use in printf
movl $.LC0, (%esp) // load string
call printf //call printf
원래 int i가 상수로 선언 되었기 때문에 컴파일러는 스택에 저장된 값 대신 리터럴 값을 사용할 권한을 보유합니다. 이것은 값이 변경되지 않고 원래 10으로 고정되어 있음을 의미합니다.
이야기의 교훈은 컴파일 시간 상수가 컴파일러에게 말하는 것이기 때문에 일정하게 유지되어야한다는 것입니다. 이야기의 교훈은 상수를 변경하기 위해 불변성을 버리면 나쁜 일로 이어질 수 있다는 것입니다.
-------------------const_cast
정의 된대로 변수의 불변성을 제거하지 않습니다. const 참조를 사용하는 메서드에 참조로 상수 가 아닌 변수를 전달하는 경우 within 값을 수정하는 데 void foo(const int& x)
사용할 수 있지만 실제로 전달한 변수가 처음에 const가 아닌 경우에만 사용할 수 있습니다 .const_cast
x
foo
상수를 다시 바인딩 할 수없는 이유는 무엇입니까? 그래서 대신
const int w = 10;
int* wp = const_cast <int*> (&w);
*wp = 20;
// some code
같은 이름의 다른 상수를 도입하십시오.
const int w = 10;
{
const int w = 20;
// the same code
}
"새"상수가 자체 값에 의존해야하는 경우 다른 상수 ( const int _w = w; const int w = _w * 2;
)를 도입해야합니다 . 불필요한 할당은 컴파일러에 의해 최적화됩니다. 왜냐하면 여러분이 질문 한 이유이기 때문에 그러한 최적화를 수행 한 것을 보았 기 때문입니다.
const 값을 변경하면 안됩니다. const라는 이유가 있으며 변경하려고 시도하면 오류가 발생할 가능성이 큽니다. const가 읽기 전용 메모리 섹션에 저장되면 액세스 위반이 발생합니다.
-------------------좋은 질문. 나는 C ++가 문맥에 따라 두 가지 다른 개념에 'const'라는 키워드를 사용한다는 사실에서 혼란이 있다고 생각합니다. 이러한 개념은 상수 및 읽기 전용 변수입니다.
컴파일 중에 'const'변수의 값을 계산할 수 있으면 실제 상수가 생성됩니다. 이러한 상수에 대한 참조는 사용될 때마다 해당 값으로 대체됩니다. 그것이 사용되는 모든 장소에 영향을 미치도록 변경할 수있는 메모리의 위치가없는 이유입니다. #define을 사용하는 것과 같습니다.
컴파일 중에 'const'변수의 값을 계산할 수없는 경우 읽기 전용 변수를 생성합니다. 값을 포함하는 메모리의 위치가 있지만 컴파일러는 읽기 전용 동작을 적용합니다.
-------------------여기에 새로 고침이 있습니다. 이것이 C에 있음을 유의해야합니다. 이것은 const
키워드를 사용하는 변수 또는 포인터의 사용에 대한 믿을 수 없을 정도로 까다로운 토대입니다 . 이것은 포인터 변수의 차이점 foo
과 said 키워드를 사용하여 그 의미를 변경할 수있는 방법을 강조합니다 .
char const * foo; char * const foo; const char * foo;
첫 번째와 마지막 선언 은 'foo'가 가리키는 데이터를 읽기 전용 으로 만들지 만 'foo'가 가리키는 주소를 변경할 수 있습니다.
const * char foo; / * 또는 char const * foo * / char str [] = "안녕하세요"; foo = & str [0]; /* 확인! * / foo [1] = 'h'; / * BZZZZTTT! 컴파일 실패! * /
위의 중간 선언은 포인터를 읽기 전용으로 만듭니다. 즉 'foo'가 가리키는 데이터의 주소를 변경할 수 없습니다.
char * const foo; char str [] = "안녕하세요"; foo = & str [0]; / * BZZZZTTT! 컴파일 실패! * /-------------------
내 생각에 w const를 선언하면 컴파일러가 w의 값을 인라인하고 명령어를 재정렬하는 것과 같은보다 적극적인 최적화를 수행 할 수 있습니다. w가 변경되는 것처럼 보이는지 여부는 정확한 경우에 적용된 최적화에 따라 다르며 사용자가 제어 할 수 없습니다.
w를 완전히 const로 만들 수는 없습니다. cons_cast는 프로그래머가 뭔가 수상한 일을하고 있다는 힌트가되어야합니다.
출처
https://stackoverflow.com/questions/2006161