(이 글은 2007년 1월 16일에 DokuWiki 에서 작성된 http://j.strane.net/dokuwiki/blog/2007/c_labyrinth_1 를 WordPress 로 옮긴 것입니다.)
Code
#include <iostream>
#include <string>
using namespace std;
class A
{
public:
A () {};
operator string() { return "It's A!"; };
};
class B
{
public:
B () {};
B (const A& temp) {};
operator string() { return "It's B!"; };
};
int main()
{
A a;
B b;
string sTemp = (true ? a : b);
cout << "What do you expect?" << endl;
cout << "Unfortunately, " << sTemp << endl;
return 0;
}
Question
위 코드를 실행했을 때 예상되는 출력 결과는 무엇일까요?
- 위 코드는 gcc 3.3.5 에서 -Wall 옵션으로 워닝이나 에러없이 컴파일됩니다.
- 리플에 정답이나 힌트가 올라올 수 있습니다. 여기까지 읽으셨다면 문제에 필요한 내용은 다 읽으신 것이니 곰곰이 생각해보시거나 컴파일하고 돌려보신 후에 더 읽기를 눌러주세요.
Answer
C++ 표준을 살펴봐야 좀 더 정확한 설명을 해드릴 수 있겠지만 우선 제가 아는 범위 내에서는 아래와 같이 설명할 수 있을 것 같습니다.
일단 C 계열은 strong-typed language 이므로 삼항 연산자의 결과값의 타입은 컴파일 타임에 결정이 되어야 합니다. 즉, (cond ? a : b) 가 있다면 이 연산자의 결과값이 무슨 타입인지를 컴파일 타임에 알아야 타입 체크를 해서 컴파일 에러를 내야할지 말지를 알 수 있겠죠. 그렇기 때문에 컴파일러는 (cond ? a : b) 에서 a 와 b 의 타입이 서로 다르면 a 와 b 의 타입을 같게 맞춰서 런타임에 cond 가 어떤 값을 가지더라도 동일한 타입을 리턴한다는 걸 보장하려고 합니다.
위 코드는 class A 타입에서 class B 타입으로 implicit conversion 이 가능하므로 컴파일러가 삼항 연산자의 결과값의 타입을 class B 라고 결정합니다. 따라서 class A 타입의 인스턴스가 리턴되는 경우에는 자동으로 class B 타입으로 변환이 되어서 나오게 되고 그래서 위와 같은 실행 결과가 나옵니다. 하지만 컴파일러가 행할 수 있는 implicit conversion 은 최대 한번까지만 가능하므로 한단계를 더 두어서 class C 까지 만들어서 짜면 아마 에러가 날 것 같습니다.

The C++ Labyrinth #1 by Woojong Koh, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
Related posts
Tags: C++, Programming, Quiz

Pingback: Codex praptor