C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[76042] Re: lambda expression this 가 implicit capture 되는 문제. 엠바 컴파일러 버그임.
빌더(TWx) [builder] 1810 읽음    2021-02-10 15:19
아루스 님이 쓰신 글 :
: 테스트 예제:
: 14] auto Test{_STD make_unique<TStringList>()};
: 15] [](TStrings * Var) {
: 16]     Var->Values["Key"] = "Value";
: 17] }(Test.get());
:
: 컴파일 에러:
: [bcc64 Error] Unit1.cpp(16): 'this' cannot be implicitly captured in this context
:
: 위와 같이 lambda expression 내부에서 capture가 필요없는 parameter의 property에 값을 쓸 경우 에러가 발생합니다.
: 암묵적 this capture에 대한 에러인데, 이 코드에서 this capture가 발생해야 할 이유를 모르겠습니다.

: 위와 같은 경우에는 Var->Add("Key=Value"); 로 바꾸면 this capture가 없어도 되긴 합니다만,
: property의 값을 바꾸는 함수가 없을 경우 모두 구현해야해서 불편함이 생기네요.




답변:


질문에 언급되어 있는 경우와 같이...

람다에서 outter scope를 참조하고 있지않고, 람다 인수로 넘어온 파라미터만 참조하고 있으므로
정상적으로 구현되어 있는 C++ 컴파일러라면 아무런 에러 없이 컴파일 할 수 있어야 합니다.


그러나...

엠바 툴은 C++ 컴파일러가 엉터리로 구현되어 있어서 에러가 발생하는 겁니다.



엠바툴에서 TStrings 클래스의 Values 프로퍼티는 다음과 같이...


1. 파스칼인 경우...
function GetValue(const Name: string): string;
procedure SetValue(const Name, Value: string);
property Values[const Name: string]: string read GetValue write SetValue;


2. C++빌더인 경우...
UnicodeString __fastcall GetValue(const UnicodeString Name);
void __fastcall SetValue(const UnicodeString Name, const UnicodeString Value);
__property UnicodeString Values[const UnicodeString Name] = {read=GetValue, write=SetValue};

으로 정의되어 있는데...


OOP 디자인 룰에서 클래스 멤버 변수는 getter()나 setter() 인터페이스 함수를 통해서 액세스 해야 하고
내부 데이타 멤버는 외부로 알려지지 않게 캡슐화 해서 사용하는 게 대원칙이라 C++에선 컴파일러가 property 신텍스를
지원하더라도 쓰는 일이 없죠.

엠바 툴에서 property 를 쓰는 것은 함수를 변수처럼 다룰 수 있는 메카니즘이 없으면 Object Inspector를 이용한
Form Design 방식이 불가능 하기 때문 입니다.


컴파일러가...

Var->Values["Key"] = "Value";

구문을 만나면 property에 정의되어 있는 패턴대로...

소스코드를... 매크로 확장하듯 

Var->SetValue("Key", "Value"); 로 치환해서 컴파일 할 뿐이죠.

디자인 타임시에 property 값을 바꾸는 것은 RTTI를 이용한 꼼수를 이용해서 Object Inspector를 구현해 놓은 것에 불과한 거고.



헐.... 손님이 와서 한가해지면 이어서 쓸게요



명절이라고 손님들이.....


부언으로...

엠바에선 RTTI라는 용어를 대서특필하듯 쓰고 있지만...
엄밀하게 보면 RTTI라기 보다는 Java 컴파일러에서의 Type Info Meta 정보와 같은 개념 입니다.

델파이 컴파일러 내부구조도 그렇고.
앤더스 헤일즈버그가 MS에서 TypeScript ( static type safty 버전의 JavaScript 라고 보면 됌) 언어를 맏고 있는 것을 보면
이 친구가 대학에서 컴파일러 이론을 Java 로 배운 듯.

컴파일러가 세세한 Type Info Meta 정보를 생성하지 않으면 Object Inspector를 이용한 Form Design 방식도 불가능 하고...
LiveBinding Design 방식도 불가능 하기 때문에 델파이로 컴파일 된 바이너리는 덩치가 커집니다.

C++에서도 RTTI (원래 의미의 RTTI) 가 사용되지만 다음과 같이...

typeid(int) == typeid(int&);

typeid가 지정되어 있는 구문에 대해서만 컴파일러가 런타임 타입 정보를 생성하므로...
모든 타입에 대해서 Type Info Meta 정보를 생성 할 수 밖에 없는 엠바 툴과는 다르죠.

델파이 Type Info Meta 내부 구조를 디테일하게 들어가려면 내용이 길어질거 같아 생략하고...
엠바 C++ 컴파일러의 Lambda 버그 문제를 다시 짚어 봅시다.



엠바 툴만 사용하는 사람들은...
VC++ 컴파일러도 property 신택스를 지원하고 있다는 것을 모르고 있는 경우가 태반일 텐데...

다음과 같이 형식만 다를 뿐.. VC++ 컴파일러도 아주 오래전 부터 이미 property 신택스를 지원하고 있지요.

__declspec(property(get = getter, put = setter)) propertyName;


엠바 C++ 컴파일러에서 정의되어 있는 TStrings 클래스의 Values 프로퍼티를...
VC++ 프로퍼티 형식으로 표현하면 다음과 같이 표현 할 수 있고.

class TStrings : public System::Classes::TStrings
{
public:
	String get_Value(const String& Name){ return __super::Values[Name]; }
	void set_Value(const String& Name, const String& Value){ __super::Values[Name] = Value; }
  __declspec(property(get = get_Value, put = set_Value)) String Values[];
};


VC++ 컴파일러의 property 신택스는 clang 컴파일러에서도 지원하므로 clang 컴파일러를 베껴서 만든
엠바 C++ 컴파일러에서도 적용할 수 있습니다. VC++ 컴파일러가 산업계에서 가장 많이 대중적으로 사용되는
메인스트림 컴파일러라 clang 도 VC++ 신택스를 지원하고 있는 거죠.

위와 같이 엠바 컴파일러에서 VC++ 형식으로 프로퍼티를 정의해서 사용하면...

질문에 언급되어 있는 구문은 다음과 같이 namespace 만 글로벌 네임스페이스로 지정해서 정상적으로 컴파일 할 수 있게 됍니다.

class TStrings : public System::Classes::TStrings
{
public:
	String get_Value(const String& Name){ return __super::Values[Name]; }
	void set_Value(const String& Name, const String& Value){ __super::Values[Name] = Value; }
  __declspec(property(get = get_Value, put = set_Value)) String Values[];
};

void __fastcall TForm2::Button1Click(TObject *Sender)
{
 auto Test{_STD make_unique< TStringList >()};

 [](auto v) {
    v->Values["Key"] = "Value";
    }((::TStrings*)Test.get());
}


TStringList도 마찬가지 입니다.


class TStringList : public System::Classes::TStringList
{
public:
	String get_Value(const String& Name){ return __super::Values[Name]; }
	void set_Value(const String& Name, const String& Value){ __super::Values[Name] = Value; }
  __declspec(property(get = get_Value, put = set_Value)) String Values[];
};

void __fastcall TForm2::Button1Click(TObject *Sender)
{
 auto Test{_STD make_unique<::TStringList>()};

 // write
 [](auto v) { v->Values["Key"] = "Value"; }(Test.get());

 // read
 Caption = [](auto v) { return v->Values["Key"]; }(Test.get());
}



컴파일러를 엉터리로 만들어 놓았다는 게 감이 오나요?


엠바 컴파일러에선...

__property UnicodeString Values[const UnicodeString Name] = {read=GetValue, write=SetValue};

[] 안에서 Name을 심볼명 처럼 쓰고 있는데, 이건 델파이 스타일 프로퍼티 신택스를 그대로 베껴서 쓴 산물에 불과한 거고.


VC++ 컴파일러 처럼 정의하는 게

__declspec(property(get = get_Value, put = set_Value)) String Values[];

C++ 문법에 맞는 겁니다.


위에서 __super는 패런트의 Context를 참조할 수 있도록 해주는 VC++ 컴파일러 키워드고
VC++ 컴파일러가 메인스트림 컴파일러로 가장 많이 쓰이는 컴파일러라 clang 컴파일러도 이 키워드를 지원하고 있지요.



결론...


람다에서 outter scope를 참조하고 있지않고, 람다 인수로 넘어온 파라미터만 참조하고 있을 뿐인데도
엠바 C++ 컴파일러에서 에러가 발생하는 이유는...


엠바가 clang 컴파일러를 엉터리로 베껴서 만들어서...
소스코드 파싱시... 람다 구문에서 프로퍼티가 Write(setter 형식) 형식으로 확장될 때...
Name을 outter scope 참조가 필요한 외부 심볼로 엉뚱하게 파싱하고 있기 때문 입니다.


엠바 C++ 컴파일러는 clang을 베껴서 만들었고..
clang에선 이미 VC++ 형식의 property 신택스를 지원하고 있으므로 clang 컴파일러 파서의 property 핸들링 소스코드만
잘 활용했더라도 문제가 없었을 텐데... 델파이 스타일 프로퍼티 신택스를 그대로 베껴서 컴파일러를 엉터리로 만든 바람에
이와 같은 컴파일러 버그를 낳게 된 거죠.




IDE, Compiler, Debugger, LSP, RTL 등등

디테일하게 들여다 보면 엠바 툴은 문제가 너무 많아요. 아마추어가 만들어 놓은 것 처럼...





+ -

관련 글 리스트
76041 lambda expression 에서 parameter의 property에 쓰기시 this 가 implicit capture 되는 문제 아루스 1519 2021/02/10
76042     Re: lambda expression this 가 implicit capture 되는 문제. 엠바 컴파일러 버그임. 빌더(TWx) 1810 2021/02/10
76073         Re:Re: lambda expression this 가 implicit capture 되는 문제. 엠바 컴파일러 버그임. 아루스 1305 2021/03/04
76048         Re:Re: 내공이 엄청나시네요 우인텍크 1552 2021/02/16
76049             Re:Re:Re: 내공이 엄청나시네요 1413 2021/02/16
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.