#define 매크로의 사용 문법을 알고 싶습니다.

vudghkzm의 이미지

c/c++ 에서 define 매크로의 다양한 용법 및 문법을 배우고 싶습니다.
그냥 #define MAX 200 이런식으로 밖에 사용한 적이 없는데, 이거 외에 굉장히 많은 용법들이 있다고 하던데, 궁금합니다.

참고할만한 사이트나 문서, 서적이 있다면 알려주세요~

thyoo의 이미지

매크로는 일반적으로 가독성을 떨어뜨립니다.

매크로는 goto문하고 비슷합니다.
goto문을 무조건적으로 쓰면 안된다는 생각이
실용주의의 시각에는 바보처럼 비춰지듯이
("If you want to go somewhere, goto is the best way to get there." Ken Thomson)
소스 보기가 나쁘기 때문에
매크로를 절대로 써서는 안된다는 생각 역시 바보같은 생각이겠지요.

C에서는 주로 퍼포먼스(inline), 조금씩 다른 반복되는 코드(template)를
위해서는 매크로를 씁니다. (상수 선언은 const C99)
그밖에도 언어에서 지원하지 않는 상속, 예외등을 구현하기 위해
쓰기도 합니다.
(C++ 코드에 매크로가 많으면 잘 못 짠 겝니다. 저는 주로 template specialization하는데
매크로를 씁니다만)

그러나, 바뜨
매크로 공부 교재를 찾으시나요?
MFC나 wxWidget를 추천합니다.
왜 매크로를 자제해야 하는 지를 온 몸으로 감동하실 겁니다.
그밖에도 내상을 입을 만큼 감동한 코드가 있읍니다.
아래는 Xine의 MPEG2 Video Decoder 코딩 스타일입니다.

#define Z x->y->z
int foo(struct A* a)
{
    return a->Z->function(a->Z);
}
#undef Z

전부 이런식입니다. 위의 소스는 간략화했지만 알송 달송한 매크로로 범벅해놨더군요.
저는 이런 코드를 보면 멀미가 나면서 저자를 찾아가 패주고 싶습니다.
또 참고할 만한 Art 싸이트는
http://www.ioccc.org/main.html

#define에서 #, ## operator만 알면 다 안다고 말할 수 있읍니다.
# operator 예 (errno값이 매크로이고 strerror()를 못쓴다는 전제하)

#define ___ERROR_ENTRY___(_x_) case _x_: return "[" #_x_ "]"
const char* errno2str(const int error_no)
{
	switch (error_no) {
	___ERROR_ENTRY___(E2BIG);
	___ERROR_ENTRY___(EACCES);
	___ERROR_ENTRY___(EADDRINUSE);
	___ERROR_ENTRY___(EADDRNOTAVAIL);
	___ERROR_ENTRY___(EAFNOSUPPORT);
	___ERROR_ENTRY___(EAGAIN);
	___ERROR_ENTRY___(EALREADY);
	___ERROR_ENTRY___(EBADF);
	...
	}
	return "[!E_NOTPOSIX]";
}

## operator 예 (비실제적인 단순예)

template<int errno_>
class Error {
public:
	const char* c_str() const { return "!E_NOTPOSIX"; }
};
 
#define DECL_ERROR( _x_ ) template<>\
	class Error<_x_> {\
	public:\
		const char* c_str() const { return #_x_; }\
	}; Error<_x_> Instance_##_x_;
 
 
DECL_ERROR(E2BIG);
DECL_ERROR(EACCES);
DECL_ERROR(EADDRINUSE);
DECL_ERROR(EADDRNOTAVAIL);
DECL_ERROR(EAFNOSUPPORT);
DECL_ERROR(EAGAIN);
DECL_ERROR(EALREADY);
DECL_ERROR(EBADF);

___________________________________
Less is More (Robert Browning)

___________________________________
Less is More (Robert Browning)

chadr의 이미지

저도 가능하면 매크로 사용은 지양하시라고 말씀드리고 싶습니다..
매크로 대용은 얼마든지 있으니 (const 변수, 인라인 함수)이를 이용하시는것이 디버깅도 쉽습니다.

ps. 매크로로 도배되어있는 DirectX Framework를 보고 있느라면 짜증이 물밀듯이 밀려오더군요.. 도통 디버깅도 어렵고#, ##연산자 때문에 툴의 지원도 제대로 못받구요..
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.