코드 조각 :
((int8_t) + (78));
이는 표현은, 다음, 값 78
소요 단항 +
을 적용 하나는 int8_t
유형, 전에 멀리 던지는 것을 던진다. 그것은 법적 표현에 진짜 차이가 없습니다 :
도 (컴파일러가 부작용이 없음을 알 수있는 경우 이러한 가능성이 존재에서 최적화 할 것이지만) 그 결과를 멀리 던져 식을 평가
42;
a + 1;
.
이러한 "누드"식은 C에서 완전히 유효하며 i++
같이 i
을 계산하여 부작용이있을 때만 유용하며 값을 증가시키는 부작용으로 버립니다.
당신이 이이 매크로를 사용해야하는 방법이의 라인을 따라 더 :
int8_t varname = INT8_C (somevalue);
겉으로는 중복 단항 +
연산자에 대한 이유는 표준에서 찾을 수 있습니다. 인용 부호있는 C99 6.5.3.3 Unary arithmetic operators /1
:
단항 + 또는 - 연산자의 피연산자는 산술 형식이어야합니다.
그리고,
6.2.5 Types, /18
에 :
정수 및 부동 유형의 집합 연산 유형이라고합니다.
즉, 단항 +
은 포인터, 복소수 또는 구조와 같은 매크로의 다른 모든 데이터 형식을 사용할 수 없도록합니다.
는 그리고 마지막으로, 이유 당신 :이 같은 일이 아니기 때문에
signed char + 78;
조각이 작동하지 않습니다이다. 이 변수는 signed char
유형의 변수를 선언하기 시작하지만 유효한 변수 이름이 아니기 때문에 +
에 도달하면 질식합니다. 당신의 작업 조각에이 상당하려면 다음을 사용 : signed char
를 입력 할 수있는 값 +78
의 캐스팅이다
(signed char) + 78;
합니다.
그리고, C99
7.8.14 Macros for integer constants /2
에 따라, 당신은 또한 그 매크로에 비 상수를 사용하여 조심해야한다는, 그들은 작동하지 않을 수있어 :
이 매크로의 인스턴스의 인수가이어야한다 해당 형식에 대한 제한을 초과하지 않는 값을 갖는 접미사가없는 정수 상수 (6.4.4.1에서 정의 된 )
6.4.4.1
단순히 다양한 접미사 (U
, UL
, ULL
, L
, LL
와 소문자 당량 유형에 따라)을 가진 다양한 정수 포맷 (십진수/진수/헥스)를 지정한다. 결론은 변수가 아닌 상수이어야한다는 것입니다.
예를 들어, glibc
이있다 : 수
# define INT8_C(c) c
# define INT16_C(c) c
# define INT32_C(c) c
# if __WORDSIZE == 64
# define INT64_C(c) C## L
# else
# define INT64_C(c) C## LL
# endif
당신의 INT8_C
잘하지만 일할 매크로 텍스트 INT64_C(val)
당신이 원하는 것, 어느 것도 valL
또는 valLL
, 하나에 사전 처리 될 것입니다.
'INT8_C'의 정의가 잘못 되었음 : 7.18.4 단락 3 : "이 매크로 중 하나의 호출 (참고 : 'INTN_C'참조)은 정수형 상수 표현으로 확장되어야하며,'# if' 전처리 지시어에 사용하기에 적합합니다. **"그 캐스트는 작동하지 않습니다 사전 처리 지시어에서는 전처리 중에 유형 (따라서 캐스트)이 존재하지 않기 때문에. 어떤 컴파일러/플랫폼을 사용하고 있습니까? 이에 대한 버그 리포트를 제출하는 것을 고려해야합니다. –
@ChrisLutz : C99에서 유효했습니다. N1256에 통합 된 Technical Corrigendum 1에서는 무효가되었습니다. 이것은 [DR # 209] (http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_209.htm)에 대한 응답이었습니다. –
@KeithThompson - 아. 나는 TC2 사본을 갖고 있으며, 꽤 최근까지는 기술 고문단을 실제로 알지 못했습니다. –