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
[76073] Re:Re: lambda expression this 가 implicit capture 되는 문제. 엠바 컴파일러 버그임.
아루스 [tinydew4] 1301 읽음    2021-03-04 10:37
우선은 메소드 호출로 처리하긴 했는데, 내용 참고해서 필요시에는 ms property를 사용해야 겠네요.
답변 감사합니다!

빌더(TWx) 님이 쓰신 글 :
: 아루스 님이 쓰신 글 :
: : 테스트 예제:
: : 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 되는 문제 아루스 1518 2021/02/10
76042     Re: lambda expression this 가 implicit capture 되는 문제. 엠바 컴파일러 버그임. 빌더(TWx) 1808 2021/02/10
76073         Re:Re: lambda expression this 가 implicit capture 되는 문제. 엠바 컴파일러 버그임. 아루스 1301 2021/03/04
76048         Re:Re: 내공이 엄청나시네요 우인텍크 1550 2021/02/16
76049             Re:Re:Re: 내공이 엄청나시네요 1410 2021/02/16
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.