함수 포인터의 역 참조는 어떻게 발생합니까?
함수 포인터를 역 참조하는 이유와 방법은 "아무것도하지 않습니다".
이것이 내가 말하는 것입니다.
#include<stdio.h>
void hello() { printf("hello"); }
int main(void) {
(*****hello)();
}
함수 포인터는 잘 참조되지 않지만 결과 함수 지정자는 즉시 함수 포인터로 다시 변환됩니다.
함수의 포인터를 역 참조하는 것은 (생각하는 방식으로) 데이터 메모리처럼 CODE 메모리에 액세스하는 것을 의미합니다.
함수 포인터는 그런 식으로 역 참조되지 않는다고 가정합니다. 대신 호출됩니다.
"호출"과 함께 "역 참조"라는 이름을 사용합니다. 괜찮아.
어쨌든 : C는 함수 이름 식별자와 변수 보유 함수의 포인터가 같은 방식으로 설계되었습니다 : CODE 메모리에 대한 주소. 그리고 식별자 나 변수에서 call () 구문을 사용하여 해당 메모리로 이동할 수 있습니다.
함수 포인터의 역 참조는 정확히 어떻게 작동합니까?
옳은 질문이 아닙니다. C의 경우 적어도 올바른 질문은
rvalue 컨텍스트에서 함수 값은 어떻게됩니까?
(과 r- 수치 컨텍스트 어디서나 이름 또는 다른 레퍼런스가 할당의 좌측 제외-기본적 위치 어딘가에 라기보다는 값으로 표기 곳에 나타난다. 이름 자체에서 유래 오른쪽 의 - 손 측 과제.)
좋습니다. rvalue 컨텍스트에서 함수 값은 어떻게됩니까? 원래 함수 값에 대한 포인터로 즉시 암시 적으로 변환됩니다. 를 사용하여 해당 포인터를 역 참조 *하면 동일한 함수 값이 다시 반환되며, 이는 즉시 암시 적으로 포인터로 변환됩니다. 그리고 원하는만큼이 작업을 수행 할 수 있습니다.
두 가지 유사한 실험을 시도 할 수 있습니다.
lvalue 컨텍스트 (할당의 왼쪽) 에서 함수 포인터를 역 참조하면 어떻게됩니까 ? (함수가 불변이라는 것을 명심한다면, 당신이 기대하는 것에 대한 대답이 될 것입니다.)
배열 값은 lvalue 컨텍스트의 포인터로도 변환되지만 배열에 대한 포인터가 아닌 요소 유형 에 대한 포인터로 변환됩니다 . 따라서 그것을 역 참조하면 배열이 아닌 요소가 제공되며 표시되는 광기는 발생하지 않습니다.
도움이 되었기를 바랍니다.
PS 함수 값이 암시 적으로 포인터로 변환 되는 이유 에 대해 대답은 함수 포인터를 사용하는 사용자에게 &'s를 모든 곳 에서 사용할 필요가 없다는 것이 매우 편리 하다는 것입니다. 또한 두 가지 편리함이 있습니다. 호출 위치의 함수 포인터가 자동으로 함수 값으로 변환되므로 *함수 포인터를 통해 호출 하기 위해 작성할 필요가 없습니다 .
PPS C 함수와 달리 C ++ 함수는 오버로드 될 수 있으며 C ++에서 의미 체계가 작동하는 방식에 대해 설명 할 자격이 없습니다.
C ++ 03 §4.3 / 1 :
함수 유형 T의 lvalue는 "T에 대한 포인터"유형의 rvalue로 변환 될 수 있습니다. 결과는 함수에 대한 포인터입니다.
단항 *연산자 와 같은 함수 참조에 대해 잘못된 연산을 시도하면 언어가 가장 먼저 시도하는 것은 표준 변환입니다. 를 int추가 할 때를 변환하는 것과 같습니다 float. 사용하여 *귀하의 예제에서, 광장 1 인 대신 포인터를 취할 함수 참조에 언어를 야기한다.
이것이 적용되는 또 다른 경우는 함수 포인터를 할당 할 때입니다.
void f() {
void (*recurse)() = f; // "f" is a reference; implicitly convert to ptr.
recurse(); // call operator is defined for pointers
}
이것은 다른 방식으로 작동 하지 않습니다 .
void f() {
void (&recurse)() = &f; // "&f" is a pointer; ERROR can't convert to ref.
recurse(); // OK - call operator is *separately* defined for references
}
함수 참조 변수는 둘러싼 범위에서 초기화 된 경우 간접 분기가 필요하지 않을 수 있음을 컴파일러에 암시하기 때문에 유용합니다 (이론적으로는 테스트 한 적이 없음).
C99에서 함수 포인터를 역 참조하면 함수 지정자가 생성됩니다. §6.3.2.1 / 4 :
함수 지정자는 함수 유형이있는 표현식입니다. sizeof 연산자 또는 단항 & 연산자의 피연산자 인 경우를 제외하고 ''함수 반환 유형 ''유형의 함수 지정자는``함수 반환 유형에 대한 포인터 ''유형이있는 표현식으로 변환됩니다.
이것은 Norman의 대답과 비슷하지만 특히 C99에는 rvalue의 개념이 없습니다.
컴파일러 작성자의 입장이되어보십시오. 함수 포인터는 잘 정의 된 의미를 가지며 기계 코드를 나타내는 바이트의 한 덩어리에 대한 포인터입니다.
What do you do when the programmer dereferences a function pointer? Do you take the first (or 8) bytes of the machine code and reinterpret that as a pointer? Odds are about 2 billion to one that this won't work. Do you declare UB? Plenty of that going around already. Or do you just ignore the attempt? You know the answer.
How exactly does dereferencing of a function pointer work?
Two steps. The first step is at compile time, the second at runtime.
In step one, the compiler sees it has a pointer and a context in which that pointer is dereferenced (such as (*pFoo)() ) so it generates code for that situation, code that will be used in step 2.
In step 2, at runtime the code is executed. The pointer contains some bytes indicating which function should be executed next. These bytes are somehow loaded into the CPU. A common case is a CPU with an explicit CALL [register] instruction. On such systems, a function pointer can be simply the address of a function in memory, and the derefencing code does nothing more than loading that address into a register followed by a CALL [register] instruction.
참고URL : https://stackoverflow.com/questions/2795575/how-does-dereferencing-of-a-function-pointer-happen
'Nice programing' 카테고리의 다른 글
| 배열 객체이지만 기본 클래스로 사용할 수없는 이유는 무엇입니까? (0) | 2020.11.15 |
|---|---|
| “ImagePullBackOff”를 디버깅하는 방법은 무엇입니까? (0) | 2020.11.15 |
| iPhone / iOS : 우편 번호 용 HTML 5 키보드 제시 (0) | 2020.11.15 |
| Android의 ListView에 이미지 목록을 표시하는 방법은 무엇입니까? (0) | 2020.11.15 |
| MATCH AGAINST 또는 LIKE 중 어떤 SQL 쿼리가 더 낫습니까? (0) | 2020.11.15 |