programing

C 매크로 정의는 다른 매크로를 참조할 수 있습니까?

kingscode 2022. 7. 16. 15:43
반응형

C 매크로 정의는 다른 매크로를 참조할 수 있습니까?

제가 알아내려고 하는 것은 다음과 같은 것(C로 작성)이 있는지 여부입니다.

#define FOO 15
#define BAR 23
#define MEH (FOO / BAR)

허용되나요?프리프로세서가 모든 인스턴스를 대체하도록 하겠습니다.

MEH

와 함께

(15 / 23)

잘 될지는 모르겠지만물론 프리프로세서가 코드를 한 번만 통과하면 내 뜻대로 되지 않을 것이다.

비슷한 예를 몇 개 찾았지만 모두 너무 복잡해서 이해할 수 없었다.이 간단한 것을 누군가 도와주면 영원히 고맙겠다!

단답 예스.정의 및 매크로를 재귀적이지 않으면 원하는 만큼 중첩할 수 있습니다.

정답은 "그렇다"이고, 다른 두 사람이 옳게 말했다.

답변이 '그렇다'인 이유에 대해서는 C 표준 섹션 6.10.3.4 "재개 및 추가 교체"에 있다.OP는 이러한 이점을 얻지 못할 수 있지만 다른 사람들은 관심을 가질 수 있습니다.

6.10.3.4 재스캔 및 추가 교체

치환 리스트 내의 모든 파라미터가 치환되고 # 및 ## 처리가 완료되면 모든 플레이스마커 전처리 토큰이 삭제됩니다.그런 다음 결과 전처리 토큰 시퀀스와 소스 파일의 후속 모든 전처리 토큰이 다시 스캔되어 더 많은 매크로 이름이 대체됩니다.

이 대체 목록 검사 중에 대체되는 매크로의 이름이 발견되면(원본 파일의 나머지 전처리 토큰은 제외) 대체되지 않습니다.게다가 네스트 된 치환에 의해서 치환되는 매크로의 이름이 발견되었을 경우, 치환되지 않습니다.이러한 대체되지 않은 매크로 이름 전처리 토큰은 나중에 해당 매크로 이름 전처리 토큰이 대체되었을 수 있는 컨텍스트에서 다시 검사(재검사)되더라도 더 이상 대체할 수 없습니다.

결과적으로 완전히 매크로로 대체되는 전처리 토큰시퀀스는 유사하더라도 전처리 디렉티브로 처리되지 않지만 그 안에 있는 모든 프래그마 단항 연산자 표현식은 다음 6.10.9에서 지정한 대로 처리됩니다.

네, 잘 될 거예요.


다만, 개인 정보에 대해서는, 매크로에 관한 간단한 룰을 몇개 소개합니다(범위외이지만, 장래에 도움이 될 가능성이 있습니다).가능한 한 간단하게 하도록 하겠습니다.

  • 정의는 포함/읽기 순서로 "정의"됩니다.즉, 이전에 정의되지 않은 정의를 사용할 수 없습니다.

  • Usefull pre-processor 키워드: #define, #undef, #else, #elif, #ifdef, #ifndef, #iffiff

  • 매크로에서 이전에 정의한 다른 #define을 사용할 수 있습니다.그들은 확장될 것이다.(질문에서와 같이)

  • 함수 매크로 정의에는 2개의 특수 연산자(# 및 ##)를 사용할 수 있습니다.

연산자 # 인수를 문자열화합니다.

#define str(x) #x
str(test); // would translate to "test"

연산자 ##은 2개의 인수를 연결합니다.

#define concat(a,b) a ## b
concat(hello, world); // would translate to "helloworld"

사용할 수 있는 (언어로부터) 미리 정의된 매크로도 몇 가지 있습니다.

__LINE__, __FILE__, __cplusplus, etc

크로스 플랫폼이 아니기 때문에 자세한 목록은 해당 컴파일러 섹션을 참조하십시오.

  • 매크로 확장에 유의하십시오.

매크로를 정의할 때 둥근 괄호("") 로그를 사용하는 것을 알 수 있습니다.그 이유는 매크로를 호출하면 매크로가 "있는 그대로" 확장되기 때문입니다.

#define mult(a, b) a * b
mult(1+2, 3+4); // will be expanded like: 1 + 2 * 3 + 4 = 11 instead of 21.
mult_fix(a, b) ((a) * (b))

네, 이 기능의 장점은 하나 더 있습니다.일부 매크로를 정의되지 않은 상태로 두고 해당 을 컴파일명령어로 다른 매크로의 이름으로 설정할 수 있습니다.

#define STR "string"
void main() { printf("value=%s\n", VALUE); }

명령줄에서 매크로 "VALUE"가 다른 매크로 "STR"에서 값을 가져온다고 할 수 있습니다.

$ gcc -o test_macro -DVALUE=STR main.c
$ ./test_macro

출력:

value=string

이 어프로치는, Windows 의 MSC 컴파일러에서도 동작합니다.매우 유연하다고 생각합니다.

내 발을 걸어 넘어뜨린 갓카를 추가하고 싶다.

기능 스타일 매크로에서는 이 작업을 수행할 수 없습니다.

사용 시 컴파일되지 않는 예:

#define FOO 1
#define FSMACRO(x) FOO + x

네, 그것은 지원되고 있습니다.그리고 꽤 많이 썼어!

하지만 한 가지 중요한 점은 표현을 수정하지 않으면 불쾌한 문제에 부딪힐 수 있다는 것을 확인하는 것입니다.

#define MEH FOO/BAR

// vs

#define MEH (FOO / BAR)

// the first could be expanded in an expression like 5 * MEH to mean something 
//   completely different than the second

언급URL : https://stackoverflow.com/questions/7972785/can-a-c-macro-definition-refer-to-other-macros

반응형