GCC 문 표현식을 사용한 익명 함수
이 질문은 매우 구체적이지 않다; 그것은 정말로 나 자신의 C 농축을 위한 것이고 나는 다른 사람들도 그것을 유용하게 여길 수 있기를 바란다.
고지 사항:나는 많은 사람들이 "FP를 하려고 한다면 기능적인 언어를 사용하라"고 대답하고 싶은 충동을 가질 것이라고 알고 있다.나는 다른 많은 C 라이브러리와 연결해야 하는 임베디드 환경에서 일하며, 더 많은 큰 공유 리브를 위한 공간이 많지 않고 많은 언어 런타임을 지원하지 않는다.게다가 동적 메모리 할당은 문제 밖이다.나 또한 정말 궁금하다.
우리 중 많은 사람들은 람다 표현에 대해 다음과 같은 니프티 C 매크로를 보았다.
#define lambda(return_type, function_body) \
({ \
return_type __fn__ function_body \
__fn__; \
})
예를 들면 다음과 같다.
int (*max)(int, int) = lambda (int, (int x, int y) { return x > y ? x : y; });
max(4, 5); // Example
사용.gcc -std=c89 -E test.c
, 람다 확장:
int (*max)(int, int) = ({ int __fn__ (int x, int y) { return x > y ? x : y; } __fn__; });
자, 제 질문은 다음과 같다.
정확히 무엇(*X)에 라인이 들어가며, 무엇을 선언하는가?물론, int * X;는 정수에 대한 포인터지만, 이 두 가지는 어떻게 다른가?
확장된 매크로를 보면, 도대체 결승전은 무엇을 하는 것일까.
__fn__
그래? 만약 내가 시험기능을 쓴다면void test() { printf("hello"); } test;
- 즉시 오류를 발생시킨다.나는 그 구문을 이해할 수 없다.이것이 디버깅에 어떤 의미가 있을까?(이것과 gdb로 내 자신을 실험할 계획이지만 다른 사람들의 경험이나 의견이 좋을 것 같다.)이것이 정적 분석기를 망칠까?
이 선언(블록 범위):
int (*max)(int, int) =
({
int __fn__ (int x, int y) { return x > y ? x : y; }
__fn__;
});
C는 아니지만 유효한 GNU C이다.
그것은 두 개를 사용한다.gcc
확장자:
내포된 함수(복합문 내 함수를 정의함)와 문 식(문 식) 모두({})
, 기본적으로 값을 산출하는 블록)은 C에서 허용되지 않으며 GNU C에서 나온다.
문 표현식에서 마지막 표현식은 구성의 값이다.이것이 내포된 함수가__fn__
문 표현식의 끝에 표현 문으로 나타난다.기능 지정자(A function administrator)__fn__
마지막 표현식에서)는 일반적인 변환에 의해 함수에 대한 포인터로 변환된다.이것은 함수 포인터 초기화에 사용되는 값이다.max
.
당신의 람다 매크로는 두 가지 펑키한 특징을 이용한다.첫째로, 그것은 실제로 당신의 기능의 본체를 정의하기 위해 중첩된 기능을 사용한다(그래서 당신의 람다는 실제로 익명이 아닌 암묵적인 기능만을 사용한다).__fn__
이름은 다른 해야 함) 변수(이중 리딩-코어 와 같은 것(이중 리딩-코어 이름)이 있을 것이다.yourapp__fn__
차라리 (그 편이 낫다.
이 모든 것은 그 자체로 GCC 복합문(http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs), 참조)에서 수행된다. http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs),의 기본 형식은 다음과 같다.
({ ...; retval; })
정의 함수의 주소가 되는 복합 문장의 마지막 문장지금int (*max)(int,int)
이제 방금 선언된 'complex' 함수에 대한 포인터가 된 복합 문 값을 간단히 할당받는다.
매크로를 디버깅하는 것은 물론 왕실의 고통이다.
그 이유에 대해서는test;
은 다른 의 기호로 씌워진다가 (이다...적어도 여기서 '시험은 다른 종류의 기호로 다시 씌워진다'는 말은 GCC가 (쓸데없는) 표현이 아니라 선언으로 취급하고 있다는 뜻일 것이다.유형화되지 않은 변수가 기본값으로 설정되어 있기 때문에int
그리고 당신이 이미 선언했기 때문에test
수수)로(수, 계속수, 계속수,void (*)(void)
이해하시겠죠..하지만 내가 틀릴 수도 있어
그러나 이것은 아무리 상상해도 휴대할 수 없다.
부분적 답변:그것은 네가 관심이 있는 것이 아니다.인트(*X)(y,z)이다.그것은 (y,z)를 취해서 (y,z)로 돌아오는 X라는 함수에 대한 함수 포인터다.
디버깅은 정말 힘들 것이다.대부분의 디버거는 매크로를 통해 추적할 수 없다.당신은 어셈블리를 디버그해야 할 것이다.
int (*max)(int, int)
선언할 변수의 유형.이것은 최대라는 이름의 함수 포인터로 정의되는데, 이 포인터들은 int를 반환하고, 2 int를 파라미터로 가져간다.__fn__
함수 이름을 말하며, 이 경우 최대값이다.나는 거기에 답이 없다.네가 전처리기기를 통해 그것을 실행했다면 네가 그것을 헤쳐나갈 수 있을 거라고 나는 상상한다.
참조URL: https://stackoverflow.com/questions/10405436/anonymous-functions-using-gcc-statement-expressions
'programing' 카테고리의 다른 글
...의 다중 정의링커 오류 (0) | 2022.05.09 |
---|---|
Vuejs 경고 예상 부울 발견 문자열 (0) | 2022.05.09 |
범위에서 랜덤 이중 생성 (0) | 2022.05.09 |
Vue 구성 요소 외부에서 변수 값을 변경하는 최상의 방법 (0) | 2022.05.09 |
경로 매개변수를 숫자로 전달하는 방법? (0) | 2022.05.09 |