(C프로그램) 매크로 정의시 안전한 방법

Posted at 2010/04/20 10:31 // in Programming // by Daniel

do { ... } while(0)로 묶기

http://kernelnewbies.org/FAQ/DoWhile0, http://kldp.org/node/41390, http://blog.dasomoli.org/220

안전한 방법은 do{}while(0)로 묶는 것입니다.

#define foo(x) do{ printf(“it’s %d\n”, x); \
                 do_something(x);\
               } while (0)

일반적으로 C에서 매크로를 짜면

#define FOO(x) \
        printf("arg is %s\n", x); \
        do_something_useful(x);

이런 식으로 짜게 됩니다.

그러나 이런 방식은 맹점이 있습니다.

예를 들어

        if (blah == 2)
                FOO(blah);

이렇게 쓰면

        if (blah == 2)
                printf("arg is %s\n", blah);
                do_something_useful(blah);;

이렇게 해석돼 버립니다.

만일 do{ … }while(0)로 만들었다면

if (blah == 2)
        do {
                printf("arg is %s\n", blah);
                do_something_useful(blah);
        } while (0);

이렇게 원하는 대로 해석됩니다.

그렇다고

        #define exch(x,y) { int tmp; tmp=x; x=y; y=tmp; }

이렇게 쓰면

if (x > y)
        exch(x,y);          // Branch 1
else 
        do_something();     // Branch 2

이런 문장이

if (x > y) {                // Single-branch if-statement!!!
        int tmp;            // The one and only branch consists
        tmp = x;            // of the block.
        x = y;
        y = tmp;
}
;                           // empty statement
else                        // ERROR!!! "parse error before else"
        do_something();
이렇게 해석돼 버립니다. –> 컴파일러 에러 발생.
그러므로 do {} while(0)로 묶는 게 최고죠. 그래서 리눅스 커널에서 모든 매크로가 그렇게 돼 있는 겁니다.

매크로에서 쓰는 변수에는 괄호를 꼭 쳐주세요

그리고 한가지 더
매크로에서 쓰는 변수에는 괄호를 꼭 쳐주세요 http://www.oualline.com/style/c06.html

/* Square a number */
#define SQUARE(X) (x * x)
/* Bad practice, no () around parameter */

이렇게 정의하면
a = SQUARE(1 + 3);
-->:
a = (1 + 3 * 1 + 3);
이렇게 돼 버려서 원치 않는 결과가 나옵니다.
/* Square a number */
#define SQUARE(X) ((x) * (x))
이러면
a = ((l + 3) * (1 + 3));
이렇게 잘 나오겠지요.
크리에이티브 커먼즈 라이센스
Creative Commons License

엑셀 매크로 : 그림을 숨기기/복구하기

Posted at 2010/04/02 10:24 // in Tips // by Daniel

http://www.developertags.com/microsoft-excel/452263/

Sub test()
s$ = "Rectangle 1"
HideUnhide s, False
Stop
HideUnhide s, True
End Sub
Sub HideUnhide(sName As String, bVisible As Boolean)
ActiveSheet.Shapes(sName).Visible = bVisible
End Sub

이렇게 쓰면 된다

토글 하려면 이렇게 쓰면 된다. (사실 Visible은 boolean 형식이 아니라 MsoTriState로 되어있다.

ActiveSheet.Shapes("Picture 1").Visible = msoTriStateToggle

처음엔 Selection쓰려고 했는데 오류났는데 인터넷 찾아보니 no need to select 라고 하는군

Sub Button2_Click()
'
' Button2_Click Macro
    s$ = "Picture 1"
    HideUnhide s, True

End Sub
Sub Button3_Click()
    s$ = "Picture 1"
    HideUnhide s, False
End Sub

Sub HideUnhide(sName As String, bVisible As Boolean)
    ActiveSheet.Shapes(sName).Visible = bVisible
End Sub

Sub Button4_Click()
    ActiveSheet.Shapes("Picture 1").Visible = msoTriStateToggle
End Sub

 

image

크리에이티브 커먼즈 라이센스
Creative Commons License