SlideShare a Scribd company logo
C 언어 시큐어 코딩 - Preprocessor-2
안전하지 않은 매크로 인자로 인한 부작용 발생을 피한다.
인자 중 하나를 두 번 이상 평가하거나 전혀 평가하지 않는 함수 형태 매크로는 안전하지 않다. 또한 할당, 증가, 감
소, 휘발성 액세스, 입출력 등의 부작용을 유발할 수 있는 함수 호출을 포함하는 매크로는 호출하지 않는다.
함수 형태 매크로 사용 시 전달 인자로 인한 부작용은 사용 방법에 대한 위험 요소이므로 그 책임은 매크로를 사용
한 프로그래머에게 있다. 하지만 이를 해결하기 위한 좋은 방법은 안전하지 않은 함수 형태의 매크로 작성을 하지
않는 것이다.
잘못된 코드 예제 - 1
매크로 인자로 인한 부작용을 보여주는 잘못된 코드 예제:
#define ABS(x) (((x) < 0) ? -(x) : (x))
void func(int n) {
/* Validate that n is within the desired range */
int m = ABS(++n);
/* ... */
}
이 예제에서 ABS() 매크로를 호출하면 다음과 같이 확장된다.
m = (((++n) < 0) ? -(++n) : (++n));
n을 두 번 증가시키는 것을 확인할 수 있다.
올바른 코드 예제 - 1.1
n의 증가 연산을 매크로 호출 전 수행하는 올바른 코드 예제:
#define ABS(x) (((x) < 0) ? -(x) : (x)) /* UNSAFE */
void func(int n) {
/* Validate that n is within the desired range */
++n;
int m = ABS(n);
/* ... */
}
추가로 ABS_UNSAFE()로 매크로 이름을 변경하여 매크로가 안전하지 않다는 것을 명확히하여 매크로를 사용하는
다른 프로그래머들의 안전한 사용을 도울 수 있으며, 부호 있는 정수에 대한 연산이 오버 플로우를 발생하지 않도록
한다.
올바른 코드 예제 - 1.2
ABS() 매크로를 대체하는 인라인 함수 iabs()를 정의한다. 모든 유형의 피연산자가 동작하는 매크로와는 달리 함수
는 데이터 형의 범위를 벗어난 인자를 자른다.
#include <complex.h>
#include <math.h>
static inline int iabs(int x) {
return (((x) < 0) ? -(x) : (x));
}
void func(int n) {
/* Validate that n is within the desired range */
int m = iabs(++n);
/* ... */
}
올바른 코드 예제 - 1.3
보다 유연한 해결책은 _Generic을 사용하여 ABS() 매크로를 선언하는 것이다. 아래 코드는 인라인 함수를 사용하여
모든 산술 데이터 형식을 지원하도록 작성되었다.
#include <complex.h>
#include <math.h>
static inline long long llabs(long long v) {
return v < 0 ? -v : v;
}
static inline long labs(long v) {
return v < 0 ? -v : v;
}
static inline int iabs(int v) {
return v < 0 ? -v : v;
}
static inline int sabs(short v) {
return v < 0 ? -v : v;
}
static inline int scabs(signed char v) {
return v < 0 ? -v : v;
}
#define ABS(v) _Generic(v, signed char : scabs, 
short : sabs, 
int : iabs, 
long : labs, 
long long : llabs, 
float : fabsf, 
double : fabs, 
long double : fabsl, 
double complex : cabs, 
float complex : cabsf, 
long double complex : cabsl)(v)
void func(int n) {
/* Validate that n is within the desired range */
int m = ABS(++n);
/* ... */
}
올바른 코드 예제(GCC) - 1.4
GCC의 __typeof를 사용하면 매크로 피연산자 값을 선언하고 동일한 유형을 임시 할당할 수 있다. 임시 할당하여
계산을 수행하므로 피연산자는 한번만 평가된다.
#define ABS(x) __extension__ ({ __typeof (x) tmp = x; 
tmp < 0 ? -tmp : tmp; })
잘못된 코드 예제(assert()) - 2
assert() 매크로는 편리한 코드 테스트 메커니즘을 제공한다. assert() 매크로의 동작은 NDEBUG 매크로 정의를 따
른다. NDEBUG 매크로가 정의되지 않은 경우 assert() 매크로는 인자를 평가 하기 위해 정의되며 결과가 0과 비교
되면 abort() 함수를 호출한다. NDEBUG가 정의되면 assert는 ((void) 0)으로 확장되도록 정의된다.
아래 코드는 부작용이 있는 표현식(index++)이 포함된 assert() 매크로의 예이다.
#include <assert.h>
#include <stddef.h>
void process(size_t index) {
assert(index++ > 0); /* Side effect */
/* ... */
}
올바른 코드 예제(assert()) - 2.1
부작용을 포함하는 표현식을 assert() 매크로 외부로 이동시켜 부작용을 방지한다.
#include <assert.h>
#include <stddef.h>
void process(size_t index) {
assert(index > 0); /* No side effect */
++index;
/* ... */
}
출처 PRE31-C. Avoid side effects in arguments to unsafe macros

More Related Content

What's hot

Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)문익 장
 
프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기
Jongwook Choi
 
가능한 C++ 스타일의 캐스트를 즐겨 쓰자
가능한 C++ 스타일의 캐스트를 즐겨 쓰자가능한 C++ 스타일의 캐스트를 즐겨 쓰자
가능한 C++ 스타일의 캐스트를 즐겨 쓰자
민욱 이
 
C++11
C++11C++11
C++11
Yubin Lim
 
Effective modern cpp item14
Effective modern cpp item14Effective modern cpp item14
Effective modern cpp item14
진화 손
 
이펙티브 C++ 789 공부
이펙티브 C++ 789 공부이펙티브 C++ 789 공부
이펙티브 C++ 789 공부
quxn6
 
Effective c++ chapter7_8_9_dcshin
Effective c++ chapter7_8_9_dcshinEffective c++ chapter7_8_9_dcshin
Effective c++ chapter7_8_9_dcshin
Dong Chan Shin
 
Hoons 닷넷 정기세미나
Hoons 닷넷 정기세미나Hoons 닷넷 정기세미나
Hoons 닷넷 정기세미나
병걸 윤
 
Secure coding-c-preprocessor-1
Secure coding-c-preprocessor-1Secure coding-c-preprocessor-1
Secure coding-c-preprocessor-1
Seungyong Lee
 
알고리즘 연합캠프 세미나 3-C (C++11 and ETC)
알고리즘 연합캠프 세미나 3-C (C++11 and ETC)알고리즘 연합캠프 세미나 3-C (C++11 and ETC)
알고리즘 연합캠프 세미나 3-C (C++11 and ETC)
HYUNJEONG KIM
 
Api design for c++ 6장
Api design for c++ 6장Api design for c++ 6장
Api design for c++ 6장Ji Hun Kim
 
C# 세미나 12회차
C# 세미나 12회차C# 세미나 12회차
C# 세미나 12회차
Jeung_mh
 
Effective c++ Chapter6
Effective c++ Chapter6Effective c++ Chapter6
Effective c++ Chapter6
세빈 정
 
[아꿈사] The C++ Programming Language 13장 템플릿
[아꿈사] The C++ Programming Language 13장 템플릿[아꿈사] The C++ Programming Language 13장 템플릿
[아꿈사] The C++ Programming Language 13장 템플릿해강
 
Windosw via c 스터디2장
Windosw via c 스터디2장Windosw via c 스터디2장
Windosw via c 스터디2장
HolyTak
 
C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발
흥배 최
 

What's hot (17)

Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)
 
프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기
 
가능한 C++ 스타일의 캐스트를 즐겨 쓰자
가능한 C++ 스타일의 캐스트를 즐겨 쓰자가능한 C++ 스타일의 캐스트를 즐겨 쓰자
가능한 C++ 스타일의 캐스트를 즐겨 쓰자
 
C++11
C++11C++11
C++11
 
Effective modern cpp item14
Effective modern cpp item14Effective modern cpp item14
Effective modern cpp item14
 
이펙티브 C++ 789 공부
이펙티브 C++ 789 공부이펙티브 C++ 789 공부
이펙티브 C++ 789 공부
 
Effective c++ chapter7_8_9_dcshin
Effective c++ chapter7_8_9_dcshinEffective c++ chapter7_8_9_dcshin
Effective c++ chapter7_8_9_dcshin
 
Hoons 닷넷 정기세미나
Hoons 닷넷 정기세미나Hoons 닷넷 정기세미나
Hoons 닷넷 정기세미나
 
Secure coding-c-preprocessor-1
Secure coding-c-preprocessor-1Secure coding-c-preprocessor-1
Secure coding-c-preprocessor-1
 
알고리즘 연합캠프 세미나 3-C (C++11 and ETC)
알고리즘 연합캠프 세미나 3-C (C++11 and ETC)알고리즘 연합캠프 세미나 3-C (C++11 and ETC)
알고리즘 연합캠프 세미나 3-C (C++11 and ETC)
 
What’s new in c++11
What’s new in c++11What’s new in c++11
What’s new in c++11
 
Api design for c++ 6장
Api design for c++ 6장Api design for c++ 6장
Api design for c++ 6장
 
C# 세미나 12회차
C# 세미나 12회차C# 세미나 12회차
C# 세미나 12회차
 
Effective c++ Chapter6
Effective c++ Chapter6Effective c++ Chapter6
Effective c++ Chapter6
 
[아꿈사] The C++ Programming Language 13장 템플릿
[아꿈사] The C++ Programming Language 13장 템플릿[아꿈사] The C++ Programming Language 13장 템플릿
[아꿈사] The C++ Programming Language 13장 템플릿
 
Windosw via c 스터디2장
Windosw via c 스터디2장Windosw via c 스터디2장
Windosw via c 스터디2장
 
C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발
 

Similar to Secure coding-c-preprocessor-2

파이썬 스터디 2주차
파이썬 스터디 2주차파이썬 스터디 2주차
파이썬 스터디 2주차
Han Sung Kim
 
일단 시작하는 코틀린
일단 시작하는 코틀린일단 시작하는 코틀린
일단 시작하는 코틀린
Park JoongSoo
 
[Gpg2권 조진현] 1.2 인라인 함수 대 매크로
[Gpg2권 조진현] 1.2 인라인 함수 대 매크로[Gpg2권 조진현] 1.2 인라인 함수 대 매크로
[Gpg2권 조진현] 1.2 인라인 함수 대 매크로진현 조
 
Lambda 란 무엇인가
Lambda 란 무엇인가Lambda 란 무엇인가
Lambda 란 무엇인가
Vong Sik Kong
 
ECMAScript 6의 새로운 것들!
ECMAScript 6의 새로운 것들!ECMAScript 6의 새로운 것들!
ECMAScript 6의 새로운 것들!
WooYoung Cho
 
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019min woog kim
 
0.javascript기본(~3일차내)
0.javascript기본(~3일차내)0.javascript기본(~3일차내)
0.javascript기본(~3일차내)Sung-hoon Ma
 
Itcookbook Asp Chapter2
Itcookbook Asp Chapter2Itcookbook Asp Chapter2
Itcookbook Asp Chapter2xyzlee
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심흥배 최
 
C++ 프로그래밍 2014-2018년 기말시험 기출문제
C++ 프로그래밍 2014-2018년 기말시험 기출문제C++ 프로그래밍 2014-2018년 기말시험 기출문제
C++ 프로그래밍 2014-2018년 기말시험 기출문제
Lee Sang-Ho
 
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
Sang Don Kim
 
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
Chris Ohk
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스
noerror
 
Macro & compilation
Macro & compilationMacro & compilation
Macro & compilation
Ikhoon Eom
 
카사 공개세미나1회 W.E.L.C.
카사 공개세미나1회  W.E.L.C.카사 공개세미나1회  W.E.L.C.
카사 공개세미나1회 W.E.L.C.Ryan Park
 
Rust
RustRust

Similar to Secure coding-c-preprocessor-2 (20)

7장매크로
7장매크로7장매크로
7장매크로
 
파이썬 스터디 2주차
파이썬 스터디 2주차파이썬 스터디 2주차
파이썬 스터디 2주차
 
일단 시작하는 코틀린
일단 시작하는 코틀린일단 시작하는 코틀린
일단 시작하는 코틀린
 
[Gpg2권 조진현] 1.2 인라인 함수 대 매크로
[Gpg2권 조진현] 1.2 인라인 함수 대 매크로[Gpg2권 조진현] 1.2 인라인 함수 대 매크로
[Gpg2권 조진현] 1.2 인라인 함수 대 매크로
 
Lambda 란 무엇인가
Lambda 란 무엇인가Lambda 란 무엇인가
Lambda 란 무엇인가
 
ECMAScript 6의 새로운 것들!
ECMAScript 6의 새로운 것들!ECMAScript 6의 새로운 것들!
ECMAScript 6의 새로운 것들!
 
technical report
technical reporttechnical report
technical report
 
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
 
0.javascript기본(~3일차내)
0.javascript기본(~3일차내)0.javascript기본(~3일차내)
0.javascript기본(~3일차내)
 
C++ api design 품질
C++ api design 품질C++ api design 품질
C++ api design 품질
 
Itcookbook Asp Chapter2
Itcookbook Asp Chapter2Itcookbook Asp Chapter2
Itcookbook Asp Chapter2
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심
 
C++ 프로그래밍 2014-2018년 기말시험 기출문제
C++ 프로그래밍 2014-2018년 기말시험 기출문제C++ 프로그래밍 2014-2018년 기말시험 기출문제
C++ 프로그래밍 2014-2018년 기말시험 기출문제
 
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
 
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스
 
Macro & compilation
Macro & compilationMacro & compilation
Macro & compilation
 
카사 공개세미나1회 W.E.L.C.
카사 공개세미나1회  W.E.L.C.카사 공개세미나1회  W.E.L.C.
카사 공개세미나1회 W.E.L.C.
 
8.다중메서드
8.다중메서드8.다중메서드
8.다중메서드
 
Rust
RustRust
Rust
 

More from Seungyong Lee

Secure coding-c-dcl-1
Secure coding-c-dcl-1Secure coding-c-dcl-1
Secure coding-c-dcl-1
Seungyong Lee
 
Linux blue borne-vulnerabilities
Linux blue borne-vulnerabilitiesLinux blue borne-vulnerabilities
Linux blue borne-vulnerabilities
Seungyong Lee
 
Sha 2017-teaser-round website attack writeup
Sha 2017-teaser-round website attack writeupSha 2017-teaser-round website attack writeup
Sha 2017-teaser-round website attack writeup
Seungyong Lee
 
윈도우 커널 익스플로잇
윈도우 커널 익스플로잇윈도우 커널 익스플로잇
윈도우 커널 익스플로잇
Seungyong Lee
 
화이트 박스 암호기법
화이트 박스 암호기법화이트 박스 암호기법
화이트 박스 암호기법
Seungyong Lee
 
Dll 하이재킹
Dll 하이재킹Dll 하이재킹
Dll 하이재킹
Seungyong Lee
 
Frida tutorial 1
Frida tutorial 1Frida tutorial 1
Frida tutorial 1
Seungyong Lee
 
C 프로그램 메모리 구조
C 프로그램 메모리 구조C 프로그램 메모리 구조
C 프로그램 메모리 구조
Seungyong Lee
 
리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리
Seungyong Lee
 
암호 기법의 소개
암호 기법의 소개암호 기법의 소개
암호 기법의 소개
Seungyong Lee
 
문자열이란 무엇인가
문자열이란 무엇인가문자열이란 무엇인가
문자열이란 무엇인가
Seungyong Lee
 

More from Seungyong Lee (11)

Secure coding-c-dcl-1
Secure coding-c-dcl-1Secure coding-c-dcl-1
Secure coding-c-dcl-1
 
Linux blue borne-vulnerabilities
Linux blue borne-vulnerabilitiesLinux blue borne-vulnerabilities
Linux blue borne-vulnerabilities
 
Sha 2017-teaser-round website attack writeup
Sha 2017-teaser-round website attack writeupSha 2017-teaser-round website attack writeup
Sha 2017-teaser-round website attack writeup
 
윈도우 커널 익스플로잇
윈도우 커널 익스플로잇윈도우 커널 익스플로잇
윈도우 커널 익스플로잇
 
화이트 박스 암호기법
화이트 박스 암호기법화이트 박스 암호기법
화이트 박스 암호기법
 
Dll 하이재킹
Dll 하이재킹Dll 하이재킹
Dll 하이재킹
 
Frida tutorial 1
Frida tutorial 1Frida tutorial 1
Frida tutorial 1
 
C 프로그램 메모리 구조
C 프로그램 메모리 구조C 프로그램 메모리 구조
C 프로그램 메모리 구조
 
리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리
 
암호 기법의 소개
암호 기법의 소개암호 기법의 소개
암호 기법의 소개
 
문자열이란 무엇인가
문자열이란 무엇인가문자열이란 무엇인가
문자열이란 무엇인가
 

Secure coding-c-preprocessor-2

  • 1. C 언어 시큐어 코딩 - Preprocessor-2 안전하지 않은 매크로 인자로 인한 부작용 발생을 피한다. 인자 중 하나를 두 번 이상 평가하거나 전혀 평가하지 않는 함수 형태 매크로는 안전하지 않다. 또한 할당, 증가, 감 소, 휘발성 액세스, 입출력 등의 부작용을 유발할 수 있는 함수 호출을 포함하는 매크로는 호출하지 않는다. 함수 형태 매크로 사용 시 전달 인자로 인한 부작용은 사용 방법에 대한 위험 요소이므로 그 책임은 매크로를 사용 한 프로그래머에게 있다. 하지만 이를 해결하기 위한 좋은 방법은 안전하지 않은 함수 형태의 매크로 작성을 하지 않는 것이다. 잘못된 코드 예제 - 1 매크로 인자로 인한 부작용을 보여주는 잘못된 코드 예제: #define ABS(x) (((x) < 0) ? -(x) : (x)) void func(int n) { /* Validate that n is within the desired range */ int m = ABS(++n); /* ... */ } 이 예제에서 ABS() 매크로를 호출하면 다음과 같이 확장된다. m = (((++n) < 0) ? -(++n) : (++n)); n을 두 번 증가시키는 것을 확인할 수 있다. 올바른 코드 예제 - 1.1 n의 증가 연산을 매크로 호출 전 수행하는 올바른 코드 예제: #define ABS(x) (((x) < 0) ? -(x) : (x)) /* UNSAFE */ void func(int n) { /* Validate that n is within the desired range */ ++n; int m = ABS(n); /* ... */ }
  • 2. 추가로 ABS_UNSAFE()로 매크로 이름을 변경하여 매크로가 안전하지 않다는 것을 명확히하여 매크로를 사용하는 다른 프로그래머들의 안전한 사용을 도울 수 있으며, 부호 있는 정수에 대한 연산이 오버 플로우를 발생하지 않도록 한다. 올바른 코드 예제 - 1.2 ABS() 매크로를 대체하는 인라인 함수 iabs()를 정의한다. 모든 유형의 피연산자가 동작하는 매크로와는 달리 함수 는 데이터 형의 범위를 벗어난 인자를 자른다. #include <complex.h> #include <math.h> static inline int iabs(int x) { return (((x) < 0) ? -(x) : (x)); } void func(int n) { /* Validate that n is within the desired range */ int m = iabs(++n); /* ... */ } 올바른 코드 예제 - 1.3 보다 유연한 해결책은 _Generic을 사용하여 ABS() 매크로를 선언하는 것이다. 아래 코드는 인라인 함수를 사용하여 모든 산술 데이터 형식을 지원하도록 작성되었다. #include <complex.h> #include <math.h> static inline long long llabs(long long v) { return v < 0 ? -v : v; } static inline long labs(long v) { return v < 0 ? -v : v; } static inline int iabs(int v) { return v < 0 ? -v : v; } static inline int sabs(short v) { return v < 0 ? -v : v; } static inline int scabs(signed char v) { return v < 0 ? -v : v; }
  • 3. #define ABS(v) _Generic(v, signed char : scabs, short : sabs, int : iabs, long : labs, long long : llabs, float : fabsf, double : fabs, long double : fabsl, double complex : cabs, float complex : cabsf, long double complex : cabsl)(v) void func(int n) { /* Validate that n is within the desired range */ int m = ABS(++n); /* ... */ } 올바른 코드 예제(GCC) - 1.4 GCC의 __typeof를 사용하면 매크로 피연산자 값을 선언하고 동일한 유형을 임시 할당할 수 있다. 임시 할당하여 계산을 수행하므로 피연산자는 한번만 평가된다. #define ABS(x) __extension__ ({ __typeof (x) tmp = x; tmp < 0 ? -tmp : tmp; }) 잘못된 코드 예제(assert()) - 2 assert() 매크로는 편리한 코드 테스트 메커니즘을 제공한다. assert() 매크로의 동작은 NDEBUG 매크로 정의를 따 른다. NDEBUG 매크로가 정의되지 않은 경우 assert() 매크로는 인자를 평가 하기 위해 정의되며 결과가 0과 비교 되면 abort() 함수를 호출한다. NDEBUG가 정의되면 assert는 ((void) 0)으로 확장되도록 정의된다. 아래 코드는 부작용이 있는 표현식(index++)이 포함된 assert() 매크로의 예이다. #include <assert.h> #include <stddef.h> void process(size_t index) { assert(index++ > 0); /* Side effect */ /* ... */ } 올바른 코드 예제(assert()) - 2.1 부작용을 포함하는 표현식을 assert() 매크로 외부로 이동시켜 부작용을 방지한다.
  • 4. #include <assert.h> #include <stddef.h> void process(size_t index) { assert(index > 0); /* No side effect */ ++index; /* ... */ } 출처 PRE31-C. Avoid side effects in arguments to unsafe macros