코드는 일부 플랫폼에서 작동하지만 휴대용이 아닙니다. 그 이유는 C가 포인터 타입에 대한 일반적인 포인터를 가지고 있지 않기 때문이다. void *
의 경우, 표준은 명시 적으로 타입과 다른 타입 간의 변환을 허용하지만, void **
의 경우는 그렇지 않습니다. 이것이 의미하는 바는 컴파일러가 *vp
의 값이 void *
이 아닌 다른 유형에서 변환되었는지 여부를 알 수있는 방법이 없으므로 명시 적으로 캐스팅 한 것을 제외한 모든 변환을 수행 할 수 없다는 것입니다.
void dont_do_this(struct a_t **a, struct b_t **b)
{
void **x = (void **) a;
*x = *b;
}
이 컴파일러는 그 선이 곳 곳에서 b_t
에 대한 포인터를 넣어 노력에도 불구하고, *x = *b
라인 void *
-b_t *
에서 암시 적 캐스트에 대해 불평하지 않습니다
이 코드를 고려
a_t
에 대한 포인터 만 넣어야합니다. 실수는 실제로 포인터를 "포인터를 어디에 둘 수있는 포인터"에 "포인터를
a_t
에 놓을 수있는 포인터"로 변환하는 이전 행에 있습니다. 이것은 가능한 암시 적 캐스트가없는 이유입니다. 산술 유형에 대한 포인터가있는 유사한 예는
C FAQ을 참조하십시오.
캐스트하면 컴파일러 경고를 종료해도 모든 포인터 유형이 동일한 내부 표현/크기 (예 : void **
및 int *
) 일 수 있으므로 위험합니다. 모든 경우에 코드를 작동하게하려면 사용해야 void *
중간 :
int *array;
void *varray = array;
void **vp = &varray;
*vp = malloc(sizeof(int) * 10);
는 "유형하지만"에 액세스하는'INT * '하는 것이 무슨 뜻 이죠? – ash
Eli Bendersky는이 주제에 관한 블로그 글을 가지고 있습니다 : http://eli.thegreenplace.net/2009/11/16/void-and-casts-in-c-and-c/ –
@MortenJensen * 그리고 무효가 아닙니다 ** –