Sablog Models/언어

삼항 연산자의 우선 순위와 싱글턴 패턴의 작성

어­리 2013. 6. 5. 17:33

LinkManager 클래스에 private LinkManager()와 private static LinkManager sInstance;가 있다고 가정하자.


예를 들면 public static LinkManager getInstance(...) 말미에서,

return sInstance == null ? sInstance = new LinkManager() : sInstance;

이런 코드는 가능하지만,

return sInstance != null ? sInstance : sInstance = new LinkManager();

이건 불가능하다. 이건 C/C++에서 업어온 삼항연산자의 정의 때문이다. C11의 정의는 다음과 같다.

(6.5.14) logical-OR-expression:
    logical-AND-expression
    logical-OR-expression || logical-AND-expression
(6.5.15) conditional-expression:
    logical-OR-expression
    logical-OR-expression ? expression : conditional-expression
(6.5.16) assignment-expression:
    conditional-expression
    unary-expression assignment-operator assignment-expression

Java 7에서도 마찬가지.

(15.24) ConditionalOrExpression:
    ConditionalAndExpression
    ConditionalOrExpression || ConditionalAndExpression
(15.25) ConditionalExpression:
    ConditionalOrExpression
    ConditionalOrExpression ? Expression : ConditionalExpression
(15.26) AssignmentExpression:
    ConditionalExpression
    Assignment
(15.26) Assignment:
    LeftHandSide AssignmentOperator AssignmentExpression

요즘 연산자를 어떻게 정의하는 게 좋은지 고민을 많이 하는데, 이 정의가 수많은 언어에 등장한다는 걸 생각하면 좋은 연산자 설계인지 아닌지 영 판단이 안 선다... 애초에 저런 구조가 하나만 가능하다는 건 컴파일러를 생각해야만 이해가 간다.

비슷하게 이상한 코딩을 다른 경우에도 할 수 있다. 멀쩡하게 절차적으로 짤 수 있는 struct allocator를 GNU C 확장을 이용해 Lisp 구조로 보이게 쓰는 것이다.

#include <stdlib.h>

struct link;
struct link *link_alloc(void *target);
void (*link_release)(struct link *) = free;

struct link {
    void *target;
};

struct link *link_alloc(void *target) {
    return target ? ({
            struct link *new_link = malloc(sizeof(struct link));
            new_link->target = target;
            new_link;
        }) : NULL;
}

아이고.

'Sablog Models > 언어' 카테고리의 다른 글

왜 abstract static은 금지되어 있는가?  (0) 2013.08.05