C++/버그 리포트(Bug report)

[BUG Report] MSVC(C++20) Closure type's special member function

kim선달 2021. 8. 11. 02:29
Select Language

마이크로소프트 컴파일러 C++20 feature 버그


1. 서론

 

C++20 에서 Closure type 이 이제 캡처가 없는 경우 특수 멤버 함수(기본 생성, 복사/이동 연산)를 제공하게 되었습니다.
여기서, 캡처가 없다는것은 실제로 내부에선 캡처된 객체를 사용하지 않더라도, 무조건 코드상에 캡처가 표시가 되어있는가를 기준으로 판단되어집니다.

 

Proposal

cppreference

expr.prim.lambda_closure


2. 예시

int x = 1;

auto lambda1 = []() { return 1; };
auto lambda2 = [&]() { return x; };
auto lambda3 = [&]() { return 1; };

 

위에서 말했듯이, 실제 내부적으로 캡처된것이 사용되는지의 여부는 중요하지 않습니다.

따라서 C++20 의 새로운 규칙에 따르면 lambda1 만 기본생성 및 복사/이동연산이 가능하고, 나머지는 모두 예전 규칙처럼 기본생성/복사/이동이 불가능하다.

 

static_assert(std::is_default_constructible_v<decltype(lambda1)> == true);
static_assert(std::is_default_constructible_v<decltype(lambda2)> == false);
static_assert(std::is_default_constructible_v<decltype(lambda3)> == false);

 

 

하지만,  Microsoft 에서 "캡처를 표기했지만,내부적으로는 캡처된 객체를 사용하지 않을때"는 캡처하지 않는 람다와 동일한 규칙이 적용되게 컴파일러를 잘못 작성하는 실수를 하게 되었다(lambda3 의 케이스에 해당).

// Only is MSVC
static_assert(std::is_default_constructible_v<decltype(lambda3)> == true); // WTF?

 

여기서 MSVC 최신 컴파일러가 다른 컴파일러들과는 다르게 혼자 이상하게 행동하는것을 확인할 수 있습니다

 

* 참고로 캡처하는 람다인지의 여부는 함수 포인터로의 캐스팅이 가능한지로 확인해볼 수 있다(실제로 확인해보면 lambda3 은 함수포인터로 캐스팅이 불가능 - 캡처하는 람다라는 의미 - 함을 확인할 수 있다. 즉, 언어적으로도 캡처하는 람다인지의 여부는 람다 내부와는 전혀 상관이 없다는 의미).


3. 버그 리포팅

 

StackOverflow를 보면 C++20은 아직도 간간히 컴파일러 버그가 발견되어져서 올라오기도 합니다.

 

혹시 제가 잘못 이해한 것 일수도 있으니, 똑똑한 형님들이 많이 계시는 StackOverflow에 해당 이슈에 대해 정리해서 질문글을 올려 보았습니다(여기에서 해당 글을 보실 수 있습니다).

조용히 올라가는 따봉수...

 

질문글을 올려 보니 답변과 댓글에서 MSVC가 표준을 지키지 않은게 맞는것 같다고 하네요!

윈도우 이놈들.. 맨날 표준 어기고 지들 맘대로 Nonstandard Behavior 문서로 만들어서 뿌리더니 이것마저도 지들 마음대로 구현하게 놔둘 순 없었습니다.

 

 

그래서 Microsoft 공식 이슈 제기 사이트인 Microsoft Developer Community에다가 이슈 리포트를 진행하였는데요,

빨리 고쳐줘라..

 

StackOverflow 에 내가 올린 글이랑 링크 달아서 대충 요약해서 이슈를 적었더니 담당자가 추가 정보를 달라고 합니다...

 


추가 정보는 컴파일 옵션이랑 로그 찍고 코드 generate하고 그런걸 말하는건데,

이건 너무 자명한거라 Compiler Explorer 링크 달아놓고 나머지는 생략을 했었습니다.

 

그래도 뭐 달라니 저거 다 따라해서 주긴 했습니다

(그런데 아마 comment만 저런식으로 달고 내부적으로 검토가 들어갔던 것 같다고 생각되네요)

 

 

하루 지나서 bot이 댓글을 달더니, 3일만에 버그가 고쳐졌다고 알림이 왔습니다!

사실 간단한거라 컴파일러 코드를 조금만 고치면 될것 같아 보이긴 했습니다

 

다만(당연히) bug fix 한게 지금 즉시 반영은 안되고, 다음 Microsoft Visual Studio 패치가 배포될 때 아마 해당 fix가 적용된 버전이 나갈거라고 하네요.

바로 다음인지는 잘 모르겠습니다. 아마 release 될때 알림이 온다고 하니 그때까지 기다려 봐야겠네요

 

 


4. 후기

 

이번 버그를 발견하게 된건 요즘 STL을 모두 최소한의 C++ 버전으로 동작하게 자체구현하는 개인 프로젝트를 하고 있는데, 구현한 type_traits의 테스트 코드를 짜던 중 발견하게 되었어요

 

뭐 오픈소스 기여 같은건 아니지만, 그래도 비표준 버그가 일찍 고쳐지니까 해당 버그 때문에 삽질하는 사람들이 미래에 없어질거라고 생각하니까 마음이 뿌듯한것 같네요 ㅎㅎ