typedef 포인터 상수 이상함
다음 코드를 고려해주시기 바랍니다.
typedef struct Person* PersonRef;
struct Person {
int age;
};
const PersonRef person = NULL;
void changePerson(PersonRef newPerson) {
person = newPerson;
}
어떤 이유에서인지 컴파일러는 읽기 전용 값을 할당할 수 없다고 불평하고 있습니다.하지만.const
키워드는 포인터를 일정하게 만들지 않아야 합니다.무슨 생각 있어요?
참고:
typedef int* intptr;
const intptr x;
다음과 같지 않습니다.
const int* x;
intptr
int를 가리키는 포인터입니다.const intptr
에 대해 상수 포인터입니다.int
, 상수를 가리키는 포인터가 아님int
.
그래서, 타이프 포인터 후에, 나는 더 이상 내용에 일관되게 만들 수 없습니까?
gcc의 매크로 유형과 같은 몇 가지 추한 방법이 있습니다.
typedef int* intptr;
intptr dummy;
const typeof(*dummy) *x;
하지만, 보다시피, 당신이 뒤에 있는 타입을 안다면, 의미가 없습니다.intptr
.
const PersonRef person = NULL;
가
struct Person*const person= NULL;
오브젝트가 아닌 포인터를 구성하는 것입니다.
위의 답변으로 이미 문제가 해결되었지만, 왜...
그래서 경험칙으로:
- 그
const
항상 이전 토큰을 참조합니다. - 만약 그런 것이 없다면, 대신 후계 토큰을 "정합"하는 것입니다.
이 규칙은 상수 포인터나 그와 똑같이 깔끔한 것에 포인터를 선언하는 데 도움이 될 수 있습니다.
어쨌든, 이 점을 염두에 두면서, 그 이유가 왜
struct Person *const person = NULL;
가변 구조물에 대한 const 포인터를 선언합니다.
생각해 보세요, 당신의 유형은 "그룹"입니다.struct Person
포인터 토큰으로*
. 그래서 글을 쓰기 위해서.
const PersonRef person = NULL;
컴파일러에 다음과 같은 내용이 표시됩니다(pseudo-code).
const [struct Person *]person = NULL;
할 일이 없으니깐.const
왼쪽, 오른쪽으로 토큰을 표시합니다.struct Person *
일정한.
음, 이것이 제가 타입디에프로 포인터를 숨기는 것을 싫어하는 이유인 것 같습니다. 반면에 저는 타입디에프로 포인터를 숨기는 것을 좋아하는 이유입니다.글쓰는건 어때요.
typedef struct Person { ... } Person;
const Person *person; /*< const person */
Person *const pointer; /*< const pointer to mutable person */
컴파일러들과 인간들에게 당신이 무엇을 하고 있는지 확실히 알 수 있을 겁니다.
유형의 결함 뒤에 포인터를 숨기지 마십시오. 이는 정말 나쁜 관행이며 버그만 생성할 것입니다.
그러한 악명 높은 버그 중 하나는 const로 선언되는 typedef:ed 포인터 유형이 직관적으로 예상하는 "constant data에 대한 non-constant pointer"가 아니라 "constant data에 대한 constant pointer"로 취급된다는 것입니다.이것은 당신의 프로그램에서 일어나는 일입니다.
해결책:
typedef struct
{
int age;
} Person;
const Person* person = NULL; // non-constant pointer to constant Person
당신은 점점 실수하고 있습니다.
error: assignment of read-only variable ‘person’
진술에 따라
person = newPerson;
왜냐하면 당신이 person을 const로 선언했기 때문에 그 값은 읽기만 가능하기 때문입니다..const 값은 변경할 수 없습니다.
만약 당신이 그 부가세를 바꾸려고 한다면 왜 그것을 일정하게 유지하고 있습니까?
remove const 키워드 당신의 코드는 잘 작동할 것입니다.
Piotr 의 (된) 로 GCC 를 수 typeof
:
static_assert(std::is_same<const int *, std::add_const_t<std::remove_pointer_t<intptr>> *>::value, "not same via type_traits");
static_assert(std::is_same<const int *, std::remove_reference_t<decltype(std::as_const(*intptr()))>*>::value, "not same via decltype");
바꿈으로써foo_t<T>
.foo<T>::type
Boost의 버전을 사용하면 C++98에서도 가능하지만, C++11 이후로는 꽤 됩니다.
또는 두 가지 다른 유형의 디프를 사용하여 일반 포인터가 아닌 경우에도 사용할 수 있습니다.예를 들어, 모든 컨테이너의iterator
그리고.const_iterator
디프를 타이프로 치다
언급URL : https://stackoverflow.com/questions/8504411/typedef-pointer-const-weirdness
'source' 카테고리의 다른 글
목표-C에서 프로토콜/딜러를 확장하는 방법은 무엇입니까? (0) | 2023.10.26 |
---|---|
wp_nav_메뉴 항목에 특징 이미지 추가 (0) | 2023.10.26 |
Laravel: 데이터베이스에 동적으로 연결 (0) | 2023.10.26 |
C와 C++의 "기준 통과"의 차이는 정확히 무엇입니까? (0) | 2023.10.26 |
최고의 자바스크립트 압축기 (0) | 2023.10.26 |