성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
[정성태] 만드실 수 있습니다. 단지, Unity 엔진 내의 스크립트와 W...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>C++의 연산자 동의어(operator synonyms), 대체 토큰</h1> <p> 이상하군요, 분명히 전에 컴파일이 잘 되었는데,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > #import "mscorlib.tlb" raw_interfaces_only \ high_property_prefixes("_get","_put","_putref") \ rename("ReportEvent", "InteropServices_ReportEvent") </pre> <br /> 이번엔 위의 import 구문으로 생성한 헤더 파일의 "or" 식별자에서,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > struct __declspec(uuid("03ec7d10-17a5-3585-9a2e-0596fcac3870")) ITrackingHandler : IDispatch { // // Raw methods provided by interface // virtual HRESULT __stdcall MarshaledObject ( /*[in]*/ VARIANT obj, /*[in]*/ struct _ObjRef * <span style='color: blue; font-weight: bold'>or</span> ) = 0; virtual HRESULT __stdcall UnmarshaledObject ( /*[in]*/ VARIANT obj, /*[in]*/ struct _ObjRef * <span style='color: blue; font-weight: bold'>or</span> ) = 0; virtual HRESULT __stdcall DisconnectedObject ( /*[in]*/ VARIANT obj ) = 0; }; </pre> <br /> 이렇게 (경고와 함께) 오류가 발생합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 3>E:\DotNetSamples\Cpp\netfx_host\netfx_host\netfx_host.cpp(13,1): <span style='color: blue; font-weight: bold'>warning C4279: 'or': identifier in type library 'mscorlib.tlb' is a keyword; use the 'rename' qualifier</span> 3>E:\DotNetSamples\Cpp\netfx_host\netfx_host\x64\Debug\mscorlib.tlh(12974,35): error C2143: syntax error: missing ')' before '||' 3>E:\DotNetSamples\Cpp\netfx_host\netfx_host\x64\Debug\mscorlib.tlh(12974,35): error C2143: syntax error: missing ';' before '||' 3>E:\DotNetSamples\Cpp\netfx_host\netfx_host\x64\Debug\mscorlib.tlh(12974,35): error C2059: syntax error: '||' 3>E:\DotNetSamples\Cpp\netfx_host\netfx_host\x64\Debug\mscorlib.tlh(12974,38): error C2059: syntax error: ')' 3>E:\DotNetSamples\Cpp\netfx_host\netfx_host\x64\Debug\mscorlib.tlh(12974,43): error C2238: unexpected token(s) preceding ';' 3>E:\DotNetSamples\Cpp\netfx_host\netfx_host\x64\Debug\mscorlib.tlh(12977,35): error C2143: syntax error: missing ')' before '||' 3>E:\DotNetSamples\Cpp\netfx_host\netfx_host\x64\Debug\mscorlib.tlh(12977,35): error C2143: syntax error: missing ';' before '||' 3>E:\DotNetSamples\Cpp\netfx_host\netfx_host\x64\Debug\mscorlib.tlh(12977,35): error C2059: syntax error: '||' 3>E:\DotNetSamples\Cpp\netfx_host\netfx_host\x64\Debug\mscorlib.tlh(12977,38): error C2059: syntax error: ')' 3>E:\DotNetSamples\Cpp\netfx_host\netfx_host\x64\Debug\mscorlib.tlh(12977,43): error C2238: unexpected token(s) preceding ';' </pre> <br /> C++에 or 연산자가 있는지 처음 알았군요. ^^; 그래서 검색해 보니,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Keywords (C++) ; <a target='tab' href='https://learn.microsoft.com/en-us/cpp/cpp/keywords-cpp'>https://learn.microsoft.com/en-us/cpp/cpp/keywords-cpp</a> </pre> <br /> "Standard C++ keywords" 영역에 "The extended operator synonyms are keywords when /permissive- or /Za (Disable language extensions) is specified. They aren't keywords when Microsoft extensions are enabled."라는 주석으로 "or"이 등록되어 있습니다.<br /> <br /> 좀 더 자세한 정보는 해당 예약어의 문서에 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Logical OR operator: || ; <a target='tab' href='https://learn.microsoft.com/en-us/cpp/cpp/logical-or-operator-pipe-pipe'>https://learn.microsoft.com/en-us/cpp/cpp/logical-or-operator-pipe-pipe</a> </pre> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: Malgun Gothic, Consolas, Verdana; COLOR: #005555'> C++ specifies or as an alternative spelling for ||. In C, the alternative spelling is provided as a macro in the <iso646.h> header. In C++, the alternative spelling is a keyword; use of <iso646.h> or the C++ equivalent <ciso646> is deprecated. In Microsoft C++, the /permissive- or /Za compiler option is required to enable the alternative spelling.<br /> </div><br /> <br /> "alternative spelling"이라고도 표현하는데 아마도 적절한 한글 번역으로는 "대체 토큰"으로 하는 듯합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C 대체 토큰 ; <a target='tab' href='https://ko.wikipedia.org/wiki/C_%EB%8C%80%EC%B2%B4_%ED%86%A0%ED%81%B0'>https://ko.wikipedia.org/wiki/C_%EB%8C%80%EC%B2%B4_%ED%86%A0%ED%81%B0</a> </pre> <br /> <hr style='width: 50%' /><br /> <br /> 정리해 보면, 일단 표준 입장에서는 C의 경우 iso646.h 헤더를 이용해 매크로로 정의되어 있지만 C++의 경우에는 분명하게 대체 토큰은 예약어라는 것입니다.<br /> <br /> 그럼 Visual C++의 경우에는 어떨까요? 일단 "Microsoft extensions"을 따르는 (기본) 모드에서는 예약어로 취급받지 않습니다. 그래서 그런 경우에는 iso646.h (또는, ciso646) 파일을 include시켜,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // iso646.h standard header // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #pragma once #ifndef _ISO646 #define _ISO646 #include <yvals_core.h> #if _STL_COMPILER_PREPROCESSOR #if !defined(__cplusplus) || defined(_MSC_EXTENSIONS) #define and && #define and_eq &= #define bitand & #define bitor | #define compl ~ #define not ! #define not_eq != #define or || #define or_eq |= #define xor ^ #define xor_eq ^= #endif // !defined(__cplusplus) || defined(_MSC_EXTENSIONS) #endif // _STL_COMPILER_PREPROCESSOR #endif // _ISO646 </pre> <br /> 매크로 정의로 취급할 수 있습니다. 하지만 현재 C++ 언어상 예약어로 취급하기 때문에 Visual C++에서도 위와 같이 헤더 파일로 처리하는 것은 deprecated라고 하며, 대신 "Microsoft extensions" 모드에서도 예약어로 취급할 수 있도록 "Configuration Properties / C/C++ / Language" 범주의 "Conformance mode"로,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > /permissive- (Standards conformance) ; <a target='tab' href='https://learn.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance'>https://learn.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance</a> </pre> <br /> 포함시켰으므로, 이 값을 "Yes (/permissive-)"로 설정하면 예약어로 받아들이게 됩니다.<br /> <br /> 혹은, 아예 "Microsoft extensions" 모드를 끄면 되는데 그 옵션이 바로 "Disable Language Extensions"로 "Yes (/Za)" 값을 설정하는 것입니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 그런데, 더욱 재미있는 글이 있군요. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C++ - 대체 토큰 사용하기 ; <a target='tab' href='https://jacking75.github.io/cpp_alternative_tokens/'>https://jacking75.github.io/cpp_alternative_tokens/</a> </pre> <br /> 그러니까, and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor, xor_eq 외에도 6개가 더 있는 것입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <% == { %> == } <: == [ :> == ] %: == # %:%: == ## </pre> <br /> 설마... 하는 마음으로 Visual C++로 코딩을 했더니... 정말 컴파일이 됩니다. ^^; (대신 에디터의 자동 들여 쓰기가 인식을 못해 살짝 불편합니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > #include <iostream> #include <functional> using namespace std; <span style='color: blue; font-weight: bold'>%:define USE_DEBUG</span> int main() { <span style='color: blue; font-weight: bold'><%</span> bool b1 = true; bool b2 = true; bool result1 = b1 and b2; bool result2 = b1 or b2; printf("%d, %d\n", result1, result2); function<int(int, int)> f = <span style='color: blue; font-weight: bold'><::></span>(int a, int b) { return a + b; }; <span style='color: blue; font-weight: bold'>%></span> <span style='color: blue; font-weight: bold'><%</span> bool b1 = true; bool b2 = true; bool result1 = b1 and b2; bool result2 = b1 or b2; printf("%d, %d\n", result1, result2); <span style='color: blue; font-weight: bold'>%></span> } </pre> <br /> 저런 의미에서 봤을 때, "연산자 동의어"는 대체 토큰의 일부라고 볼 수 있을 것입니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 그런데... 왜 이런 걸 굳이 만들었을까... 궁금했는데 위키 문서에 다음과 같은 글이 있군요. ^^<br /> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: Malgun Gothic, Consolas, Verdana; COLOR: #005555'> 대체 토큰을 통하여 프로그래머에게 하여금 <span style='color: blue; font-weight: bold'>일부 국제 표준과 비쿼티 키보드에선 입력하기 어려울 수 있는</span> C언어의 비트 및 논리 연산자를 쓸 수 있도록 해준다. 많은 지역적 차이로 구성된 7비트 문자가 담긴 ISO/IEC 646 표준을 참조하는 이 헤더 파일의 이름 중 일부는 C 연산자에 의해 쓰이는 문장 부호를 대체하는 악센트 문자가 있다. </div><br /> <br /> <hr style='width: 50%' /><br /> <br /> 대체 토큰에 정신이 팔려, 원래 오류가 난 코드의 해결책을 이제서야 쓰는군요. ^^ 당연히 /permissive- 옵션을 해제하거나 하는 등의 방법을 써도 되지만, import 구문에서 제공하는 rename을 다시 한번 적용하면 됩니다. 이렇게!<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > #import "mscorlib.tlb" raw_interfaces_only \ high_property_prefixes("_get","_put","_putref") \ rename("ReportEvent", "InteropServices_ReportEvent") \ <span style='color: blue; font-weight: bold'>rename("or", "_or_")</span> </pre> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
6357
(왼쪽의 숫자를 입력해야 합니다.)