MoreEffectiveC++의 Item 26 'Limiting the number of objects of a class. 를 보면 다음과 같은 부분이 있다.
{{|
The second subtlety has to do with the interaction of inlining and static objects inside functions. Look again at the code for the non-member version of thePrinter: ¤ Item M26, P17
Printer& thePrinter()
{
static Printer p;
return p;
}
Except for the first time through this function (when p must be constructed), this is a one-line function — it consists entirely of the statement "return p;". If ever there were a good candidate for inlining, this function would certainly seem to be the one. Yet it's not declared inline. Why not? ¤ Item M26, P18
Consider for a moment why you'd declare an object to be static. It's usually because you want only a single copy of that object, right? Now consider what inline means. Conceptually, it means compilers should replace each call to the function with a copy of the function body, but for non-member functions, it also means something else. It means the functions in question have internal linkage.
You don't ordinarily need to worry about such linguistic mumbo jumbo, but there is one thing you must remember: functions with internal linkage may be duplicated within a program (i.e., the object code for the program may contain more than one copy of each function with internal linkage), and this duplication includes static objects contained within the functions. The result? If you create an inline non-member function containing a local static object, you may end up with more than one copy of the static object in your program! So don't create inline non-member functions that contain local static data.(9)
9) In July 1996, the °ISO/ANSI standardization committee changed the default linkage of inline functions to external, so the problem I describe here has been eliminated, at least on paper. Your compilers may not yet be in accord with °the standard, however, so your best bet is still to shy away from inline functions with static data. ¤ Item M26, P61
|}}
C++ 에서
SingletonPattern 을 구현할때 다음과 같은 방식을 사용하고는 한다.
~cpp
Object& theObject() // 이 함수는 클래스의 정적 메소드나
// friend 함수에서 호출된다.
{
static Object obj;
return obj;
}
처음 선언될 때를 제외하고는 저 함수는
~cpp
Object& theObject()
{
return obj;
}
와 같은 의미가 된다. 이것은 inline 으로 선언할거리가 될것 같기도 하지만 inline 으로 선언되지 않았다. 왜일까? (Except for the first time through this function (when p must be constructed), this is a one-line function — it consists entirely of the statement "return p;". If ever there were a good candidate for inlining, this function would certainly seem to be the one. Yet it's not declared inline. Why not? )
그것은 바로
InternalLinkage 때문이다.
InternalLinkage 란, 컴파일 단위(translation unit -> Object Code로 생각해 보자) 내에서 객체나 함수의 이름이 공유되는 방식을 일컫는다. 즉, 객체의 이름이나 함수의 이름은 주어진 컴파일 단위 안에서만 의미를 가진다.
예를들어, 함수 f가
InternalLinkage를 가지면, 목적코드(Translation Unit) a.obj 에 들어있는 함수 f와 목적코드 c.obj 에 들어있는 함수 f는 동일한 코드임에도 별개의 함수로 인식되어 중복된 코드가 생성된다.
DeleteMe 이 말도 이해가 안갑니다. 주제로 시작한 inline은 중복 코드를 감안하고 성능을 위해서 쓰는 것이 아니 었던가요? 무엇이 문제인가요? inline 이 아닌 함수들은 ExternalLinkage로 전제 되었다고 볼수 있는데, 지적해야 할것은 inline의 operation에 해당하는 코드가 아니라, static 같은 변수가 중복을 예로 들어야 할것을... --NeoCoin
하지만
InternalLinkage가 초례하는 문제는 1996
~cpp ISO/ANSI C++
표준화 작업에서 인라인함수(
InlineFunction)를
ExternalLinkage 로 변경해서 문제가 되지 않는다.(최근의 컴파일러들은 지원한다.).
(->)
즉.. static 이라해도 각각의 obj 파일에 코드가 따로 들어가.. 객체가 중복 생성된다는 이야기인가..?
암튼,결론이 어떻게 되나요? singleton 을 구현하는 용도로 자주 쓰는 static 변수를 사용하는 (주로 getInstance류) 메소드에서는 inline 을 쓰지 말자 인가요? --1002
- 구형 컴파일러에서는 문제가 될 수 있지만 최근의 컴파일러에는 문제될게 없다고 말하는것 같습니다. 제 생각이 잘못된 것이라면 거침없는 지적을..^^; -
임인택
여기서 말하는 구형이란, 1996년에 변경된 표준을 지키지 않은 컴파일 것이다. 99년에 이책을 처음 접할때 오래되었다는 생각은 안들었는데... MEC++ 는 고전이 될수는 없는걸까.. --NeoCoin