source

typedef 포인터 상수 이상함

nicesource 2023. 10. 26. 21:14
반응형

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;

intptrint를 가리키는 포인터입니다.const intptr에 대해 상수 포인터입니다.int, 상수를 가리키는 포인터가 아님int.

그래서, 타이프 포인터 후에, 나는 더 이상 내용에 일관되게 만들 수 없습니까?

gcc의 매크로 유형과 같은 몇 가지 추한 방법이 있습니다.

typedef int* intptr;
intptr dummy;
const typeof(*dummy) *x;

하지만, 보다시피, 당신이 뒤에 있는 타입을 안다면, 의미가 없습니다.intptr.

const PersonRef person = NULL;

struct Person*const person= NULL;

오브젝트가 아닌 포인터를 구성하는 것입니다.

위의 답변으로 이미 문제가 해결되었지만, 왜...

그래서 경험칙으로:

  1. const항상 이전 토큰을 참조합니다.
  2. 만약 그런 것이 없다면, 대신 후계 토큰을 "정합"하는 것입니다.

이 규칙은 상수 포인터나 그와 똑같이 깔끔한 것에 포인터를 선언하는 데 도움이 될 수 있습니다.

어쨌든, 이 점을 염두에 두면서, 그 이유가 왜

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>::typeBoost의 버전을 사용하면 C++98에서도 가능하지만, C++11 이후로는 꽤 됩니다.


또는 두 가지 다른 유형의 디프를 사용하여 일반 포인터가 아닌 경우에도 사용할 수 있습니다.예를 들어, 모든 컨테이너의iterator그리고.const_iterator디프를 타이프로 치다

언급URL : https://stackoverflow.com/questions/8504411/typedef-pointer-const-weirdness

반응형