programing

gcc 표준 헤더에 괄호가 너무 많습니다.

stoneblock 2023. 7. 8. 10:32

gcc 표준 헤더에 괄호가 너무 많습니다.

GCC 헤더 파일의 상수 표현식이 괄호로 둘러싸인 이유는 무엇입니까?

#define INTMAX_MIN (-9223372036854775807LL)
#define INTMAX_MAX (9223372036854775807LL)

이런 식으로 괄호를 생략하면 무엇이 달라질까요?

#define INTMAX_MIN -9223372036854775807LL
#define INTMAX_MAX 9223372036854775807LL

그리고 왜 'L' 접미사가 있죠?제가 다음과 같이 적어도 똑같을까요?

#define INTMAX_MIN -9223372036854775807
#define INTMAX_MAX 9223372036854775807

실제 유용성이 있습니까, 아니면 항상 같은 것입니까?

저는 'L'이 길다는 것을 알고 있고, C 매크로에서 괄호의 중요성을 잘 알고 있습니다. 호기심 때문에 물어보는 것입니다.

만약 당신이 썼다면

a = 7 INTMAX_MIN;

구문 오류가 발생할 것으로 예상됩니다. 표면적으로는 잘못된 표현이 될 수 있기 때문입니다.그리고 그렇게 될 것입니다, 왜냐하면 그것은 확장되기 때문입니다.

a = 7 (-9223372036854775807LL);

구문 오류가 발생합니다.그러나 괄호가 없으면 다음과 같이 확장됩니다.

a = 7 -9223372036854775807LL;

당신이 의도한 것이 아님에도 불구하고, 그것은 당신에게 오류를 주지 않습니다.

더 일반적으로, 이 모든 정의는 식별자처럼 보이는 것들에 대한 확장을 제공합니다.산술식에서 식별자는 "1차 식"이지만 -922372036854775807LL은 아닙니다.그러나 괄호로 묶은 표현식은 "기본 표현식"입니다.

그리고 그것이 진짜 이유입니다.따라서 매크로는 기본 표현식처럼 보이는 것을 기본 표현식으로 확장합니다.당신은 일어난 일에 절대 놀라지 않을 것입니다.프로그래밍에서 서프라이즈는 보통 좋지 않습니다.

보통은 문제가 되지 않지만, 정의를 작성한 사람들은 보통 그것들이 작동하는 것을 원하지 않습니다.그들은 그들이 항상 일하기를 원합니다.

은 이 을 LL 형식으로 합니다.long long일반적으로 64비트입니다.LL 접미사가 없으면 리터럴은 int, long int 또는 long long int로 해석될 수 있으며, 이 중 첫 번째는 64비트 값을 지원하는 것입니다.유형을 결정하는 것은 값을 결정하는 것만큼이나 중요할 수 있습니다.

다음과 같은 정수 상수와 단항 연산자를 가진 매크로에 괄호를 두는 것이 좋습니다.

#define BLA (-1)

연산자로서 (단항연산자(자▁(▁as산연단()-여기) C에서 가장 높은 우선 순위를 가지고 있지 않습니다.사후 수정 연산자는 단항 연산자보다 우선 순위가 높습니다.예를 들어, C에는 음의 상수가 없습니다.-1는 다음과 같이 앞에 오는 상수 식입니다.-단항 연산자

별도의 PC-Lint는 이러한 매크로에 괄호를 사용하는 것을 제안합니다.

(규칙 973): 괄호 #define N(-1) 매크로 'Symbol'의 단항 연산자가 괄호로 표시되지 않음 - 식과 유사한 매크로에 나타나는 단항 연산자가 괄호로 표시되지 않습니다.예:

#define N -1

사용자는 다음과 같은 항목을 괄호로 묶는 것을 선호할 수 있습니다.

#define N (-1)

이 대답은 왜 그런지 보여주려고 노력합니다.LL필요합니다.(쉽지 않습니다.)
다른 답변들은 괄호가 필요한 이유를 보여주었습니다.

매크로 세 개를 코드화해 봅시다. 모두 10진수 상수입니다.

#define MAXILL (9223372036854775807LL)
#define MAXIL  (9223372036854775807L)
#define MAXI   (9223372036854775807)

그럼에도 불구하고.MAXI접미사가 없으므로 형식이 되지 않습니다.int.MAXI그것이 맞는 첫 번째 유형을 가질 것입니다.int,long,long long또는 확장 정수 유형입니다.

그럼에도 불구하고.MAXIL을 가지고 있습니다.L접미사, 적합한 첫 번째 유형을 가질 것입니다.long,long long또는 확장 정수 유형입니다.

그럼에도 불구하고.MAXILL을 가지고 있습니다.LL접미사, 적합한 첫 번째 유형을 가질 것입니다.long long또는 확장 정수 유형입니다.

모든 경우 매크로의 값은 동일하지만 유형이 다를 수 있습니다.

형식 결정은 C11dr § 6.4.4.15를 참조하십시오.


인쇄를 해보고 한 번 해보겠습니다.int그리고.long32비트 및long long그리고.intmax_t64입니다.

printf("I   %d %d %d",       MAXI, MAXIL, MAXILL);    //Error: type mismatch
printf("LI  %ld %ld %ld",    MAXI, MAXIL, MAXILL);    //Error: type mismatch
printf("LLI %lld %lld %lld", MAXI, MAXIL, MAXILL);    //Ok

마지막 줄에 있는 세 개의 매크로가 모두 맞듯이 세 개의 매크로도 모두 맞습니다.long long앞의 것은 형식 지정자와 숫자 사이에 형식이 잘못 입력되었습니다.

우리가 가지고 있다면,int32비트 및long,long long그리고.intmax_t는 64이며, 다음은 정확합니다.

printf("LI  %ld %ld",    MAXI, MAXIL);
printf("LLI %lld", MAXILL);

최대 폭 정수 유형의 형식 지정자는 다음과 같습니다."%" PRIdMAX이 매크로는 다음으로 확장할 수 없습니다."%ld" 그리고. "%lld"수용하기 위해MAXI, MAXIL, MAXILL로 설정됩니다."%lld"및 관련 번호intmax_t같은 유형이어야 합니다.이 경우에는,long long유일한 형태MAXILL사용해야 합니다.


다른 구현체는 확장 정수 유형을 가질 수 있습니다(예:int128_t), 이 경우 구현 특정 접미사 또는 일부 메커니즘을 사용할 수 있습니다.

언급URL : https://stackoverflow.com/questions/27663815/so-many-parentheses-in-gcc-standard-headers