SlideShare una empresa de Scribd logo
1 de 71
Descargar para leer sin conexión
옥찬호 / Nexon Korea, C++ Korea
새 C++은 새 Visual Studio에?
- 좌충우돌 마이그레이션 이야기
소개
• 옥찬호 (Chris Ohk)
• Nexon Korea Game Programmer
• Microsoft Visual C++ MVP
• 페이스북 그룹 C++ Korea 대표
• IT 전문서 집필 및 번역 다수
• 게임샐러드로 코드 한 줄 없이 게임 만들기 (2013)
• 유니티 Shader와 Effect 제작 (2014)
• 2D 게임 프로그래밍 (2014)
• 러스트 핵심 노트 (2017)
• ing…
시작하기 전에…
• 현재 서비스 중인 프로젝트를 Visual Studio 2008에서
Visual Studio 2015로 마이그레이션하면서 겪었던
문제들과 해결 방안에 대해 설명합니다.
• 마이그레이션을 하면서 겪었던 문제 중
공유드릴만한 내용을 간추려서 설명합니다.
• 마이그레이션을 하면서 겪게 되는 문제와 해결 방안은
프로젝트마다 다를 수 있음을 참고해주시기 바랍니다.
What is project migration?
하나의 시스템, 플랫폼, 애플리케이션, 위치 또는 인프라 집합에
서 하나 이상의 프로젝트 관련 항목을 다른 곳으로 옮기는 것과
연관된 프로세스 및 프로젝트 작업
https://www.if4it.com/SYNTHESIZED/GLOSSARY/P/Project_Migration.html
Statistics of project migration in 2015
66%
of IT pros delayed a migration due to past experience.
44%
experienced a migration failure in 2015
75%
of companies that performed a migration in 2015 were
offline for 48 hours or longer
http://www.itworld.co.kr/print/101274
Difficulties of project migration
• 일정 관리 문제 – 프로젝트 진행 기간을 산출하기 어려움
• 종속성 문제 – 최신 버전에 대한 라이브러리 미지원
• 안전성 문제 – 라이브 서비스에 문제가 생길 수도 있다는 불안
• 관리 문제 – 라이브 서비스 컨텐츠 개발과 동시에 진행해야 함
• 인력 문제 – 마이그레이션 작업을 담당할 사람이 부족함
• …
However…
However…
Table of Contents
• 마이그레이션 작업 전
• 마이그레이션 작업
• 마이그레이션 작업 후
• Visual Studio 2015의 유용한 기능 - Code Analysis
• 정리
마이그레이션 작업 전
Library Check
• 프로젝트에 종속되어 있는 라이브러리가
마이그레이션할 Visual Studio 버전을 지원하는지 확인
• 지원하는 경우, 해당 버전의 라이브러리 파일 다운로드 (32 / 64비트 주의)
• 지원하지 않는 경우, 대체 가능한 라이브러리 찾아보기
• 상용 라이브러리의 경우, 해당 버전의 라이브러리 지원 여부에 따라
비용이 들어갈 수도 있으므로 반드시 확인해야 함
• 비용이 너무 많이 들 경우, 포기해야 될 수도 있음
Migration Policy
• Output 폴더와 Library 폴더에 대한 정책 수립
• Output 폴더 정리
• 중간 파일 사용 여부
• 배치 파일 템플릿 작성
• Library 폴더 정리
• 프로젝트에서 사용하지 않는 라이브러리 확인
• 사용하지 않는 라이브러리에 대해 마크 표시한 뒤 차후에 삭제
Fork Branch
• 고려해야 할 사항
• 라이브 서비스 중인 프로젝트에 영향이 생겨서는 안 됨
• 마이그레이션 작업 후 모든 기능에 이상이 없는지 검사한 뒤,
문제가 없을 경우에만 새로운 프로젝트에서 작업해야 함
• 수정하는 코드가 많은 경우, 다른 기능에 영향을 줄 수 있기에
가능한 오랜 시간 동안 검증할 수 있어야 함 (프로그램 안전성↑)
Migration Branch
Root
저장소
Migration
저장소
Root
저장소
ㆍㆍㆍ
ㆍㆍㆍ
Note
• Visual Studio 2015 설치 시 Windows 8.1 SDK 및 유니버셜
CRT SDK 설치 필요 (Community 버전 기준으로 기본 설치됨)
• afxres.h 파일이 없어 빌드 오류가 발생하면 winresrc.h로 대체
• 상속 속성 페이지 파일 확장자가 .vcprops에서 .props로 변경됨
• 프로젝트에서 필터를 관리하는 파일 확장자 추가 : .filters
• 프로젝트 파일 확장자가 .vcproj에서 .vcxproj로 변경됨
마이그레이션 작업
STLport
• C++ 표준 라이브러리의 포터블 버전
• 1997년 1월, Boris Fomitchev가 개발 시작
• 상용 프로그램에서도 무료로 사용 가능
• 2008년 12월 10일, 마지막 버전 릴리즈 (5.2.1)
• 구버전의 Visual Studio 프로젝트에서 많이 사용
Why use STLport?
Why use STLport?
Why use STLport?
• 사례 1 : std::vector
std::vector<std::string> data;
data.push_back("abc");
data.push_back("123");
data.push_back("가나다");
warning C4786:
'std::reverse_iterator<std::basic_string<char,std::char_
traits<char>,std::allocator<char>> const*,
std::basic_string<char,std::char_traits<char>,
std::allocator<char> >,std::basic_string<char,
std::char_traits<char>,std::allocator<char> > const &,
std::basic_string<char,std::char_traits<char>,
std::allocator<char> > const *,int>' : identifier was
truncated to ‘255’ characters in the debug information
Why use STLport?
• 사례 2 : std::map
std::map<std::string, std::string> data;
data.insert(std::make_pair("123", "숫자"));
data.insert(std::make_pair("가나다", "한글"));
std::map<std::string, std::string> data;
data.insert(std::make_pair(std::string("123"), std::string("숫자")); // OK
data.insert(std::make_pair(std::string("가나다"), std::string("한글")); // OK
// Error
// Error
Why use STLport?
Why use STLport?
• 구버전의 Visual Studio에서 STL 지원과 관련된 많은 문제 발생
• 따라서 가볍고 보다 안정적인 STLport를 사용하게 됨
• 하지만 Visual Studio 2005를 기점으로
STL 지원과 관련된 문제들은 거의 발생하지 않음
• Visual Studio 최신 버전에서는 벡터 병렬 계산 등이 도입되면서
속도 측면에서도 많이 개선됨 → 바꾸지 않을 이유가 없다!
STLPort Removal
• 이제 제거해 봅시다.
STLPort Removal
잠시 뒤…
STLPort Removal
STLPort Removal
• 오류의 원인 1 : STLPort에는 있는데, STL에는 없는 자료구조
• hash_map (https://www.sgi.com/tech/stl/hash_map.html)
• hash_set (https://www.sgi.com/tech/stl/hash_set.html)
#include <hash_set>
typedef std::hash_set<DWORD> CHashSet;
#include <hash_map>
typedef std::hash_map<DWORD> CHashMap;
STLPort Removal
• 해결 방법
• hash_map은 unordered_map으로 변경
• hash_set은 unordered_set으로 변경
//#include <hash_set>
//typedef std::hash_set<DWORD> CHashSet;
#include <unordered_set>
typedef std::unordered_set<DWORD> CHashSet;
//#include <hash_map>
//typedef std::hash_map<DWORD> CHashMap;
#include <unordered_map>
typedef std::unordered_map<DWORD> CHashMap;
#if (_MSC_VER >= 1900)
#include <unordered_set>
typedef std::unordered_set<DWORD> CHashSet;
#include <unordered_map>
typedef std::unordered_map<DWORD> CHashMap;
#else
#include <hash_set>
typedef std::hash_set<DWORD> CHashSet;
#include <hash_map>
typedef std::hash_map<DWORD> CHashMap;
#endif
STLPort Removal
• 참고 사항 : 기존 프로젝트와 충돌이 나지 않도록 전처리
STLPort Removal
• 오류의 원인 2 : push_back()
• STLPort에서는 매개 변수 없는 push_back()을 허용
struct Data
{
double weight;
double height;
};
std::vector<Data> data;
int index = -1;
// Add Data
data.push_back();
index++;
data[index].weight = 60.0;
data[index].height = 180.0;
STLPort Removal
• 해결 방법
• 변수를 하나 선언한 뒤, 데이터를 채우고 push_back()
// Add Data
//data.push_back();
//index++;
//data[index].weight = 60.0;
//data[index].height = 180.0;
Data tempData;
tempData.weight = 60.0;
tempData.height = 180.0;
data.push_back(tempData);
void func(const char* str)
{
if (str && *str)
{
int size = strlen(str);
std::string::const_iterator begin = str;
std::string::const_iterator end = begin + size;
...
}
}
STLPort Removal
• 오류의 원인 3 : 포인터 기반 반복자
• STLPort의 const_iterator는 const char*
STLPort Removal
• 해결 방법
• const_iterator를 표준 반복자로 변환
void func(const char* str)
{
if (str && *str)
{
std::string text(str);
std::string::const_iterator begin = text.cbegin();
std::string::const_iterator end = text.cend();
...
}
}
STLPort Removal
• 참고 사항 : 기존 프로젝트와 충돌이 나지 않도록 전처리
(STLPort는 cbegin, cend 함수를 지원하지 않음)
#if (_MSC_VER >= 1900)
std::string::const_iterator itbegin = token.cbegin();
std::string::const_iterator itend = token.cend();
#else
std::string::const_iterator itbegin = token.begin();
std::string::const_iterator itend = token.end();
#endif
STLPort Removal
• 종속 관계를 갖는 프로젝트가 많은 경우, STLPort를 제거해도
포함된 .lib나 .dll로 인해 완전히 제거되지 않는 경우가 있음
STLPort Removal
• 해결 방법 : 프로젝트 종속 관계를 파악한 뒤, 풀어나간다.
STLPort Removal
• 주의 : 실타래를 풀다가 지칠 수도 있으니 숨을 쉬어가면서 하자.
STL Function Change
• 경우 1 : round() 함수 변화
• C99
• C++11
double round(double x);
float roundf(float x);
long double roundl(long double x);
double round(double x);
float round(float x);
long double round(long double x);
double round(T x); // additional overloads for integral types
STL Function Change
• 경우 2 : 곧 없어지는 auto_ptr (C++17에서 없어질 예정)
• unique_ptr
• shared_ptr
• weak_ptr
std::unique_ptr<Data> pUnique;
auto pUnique2 = std::make_unique<Data>();
std::shared_ptr<Data> pShared;
auto pShared2 = std::make_shared<Data>();
std::weak_ptr<Data> pWeak;
auto pWeak2 = pShared;
Macro Change
• 경우 1 : 매크로 / 매크로 함수 구분
#define DECLARE_FUNCTION
#define DECLARE_FUNCTION_()
class Test
{
DECLARE_FUNCTION(); // Error
DECLARE_FUNCTION_(); // OK
};
Macro Change
• 경우 2 : 매크로 문자열 사용 시 구분을 위한 공백 필요
#define MACROSTR "STRING MACRO"
const char* ERROR = "error"MACROSTR "error"; // Error
const char* VALID = "valid" MACROSTR "error"; // OK
Windows XP Support
• Visual Studio 최신 버전에서는 기본적으로 Windows XP를
지원하지 않음 → Windows XP를 지원하는 프로그램에서 문제!
• 해결 방법 : 프로젝트 속성에서 “Platform Toolset”을 “Visual
Studio 2015”에서 “Visual Studio 2015 – Windows XP”로 변경
Magic Statics
• 다음과 같은 클래스가 있다고 하자
class Single
{
private:
Single() { std::cout << "Constructorn"; }
public:
~Single() { std::cout << "Destructorn"; }
static Single& Instance() { static Single s; return s; }
};
Magic Statics
• Visual Studio 2015에서 프로젝트를 빌드한 뒤 실행할 때
싱글턴 패턴으로 구현한 클래스 타입에 대한 인스턴스를
static으로 정의할 경우 Lock이 걸린 뒤 풀리지 않아
무한 루프에 빠지는 현상이 발생
Magic Statics
• 원인 : C++11부터 지역 static 개체 생성이 스레드 안전하게 보
장하도록 표준에 추가됨 → 이를 “Magic Statics”라고 함
(https://msdn.microsoft.com/en-us/library/hh567368.aspx)
• Magic Statics에 대한 자세한 내용은 C++11 표준 문서 참조
“Dynamic Initialization and Destruction with Concurrency”
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm)
Magic Statics
• Visual Studio 2015가 static 지역 개체 초기화를
스레드 안전하게 하기 위해서 사용하는 전략
- Lock과 TLS(Thread Local Storage)
int const Uninitialized = 0;
int const BeingInitialized = -1;
int const EpochStart = INT_MIN;
// Access to these variables is guarded in the below functions. They may only
// be modified while the lock is held. _Tss_epoch is readable from user
// code and is read without taking the lock.
extern "C"
{
int _Init_global_epoch = EpochStart;
__declspec(thread) int _Init_thread_epoch = EpochStart;
}
static CRITICAL_SECTION _Tss_mutex;
static CONDITION_VARIABLE _Tss_cv;
static HANDLE _Tss_event;
static decltype(SleepConditionVariableCS)* encoded_sleep_condition_variable_cs;
static decltype(WakeAllConditionVariable)* encoded_wake_all_condition_variable;
Magic Statics
Magic Statics
• 앞의 Single 클래스 예제를 다시 가져와 보자
class Single
{
private:
Single() { std::cout << "Constructorn"; }
public:
~Single() { std::cout << "Destructorn"; }
static Single& Instance() { static Single s; return s; }
};
Magic Statics
• Visual Studio 2015는 다음과 같은 형태로 코드를 만든다
int g_single_once = Uninitialized;
static Single& Single::Instance() {
if (g_single_once > _Init_thread_epoch) {
_Init_thread_header(&g_single_once);
if (g_single_once == BeingInitialized) {
Single::Single();
atexit(Single::~Single);
_Init_thread_footer(&g_single_once);
}
}
}
Magic Statics
• Visual Studio 2015는 다음과 같은 형태로 코드를 만든다
int g_single_once = Uninitialized;
static Single& Single::Instance() {
if (g_single_once > _Init_thread_epoch) {
_Init_thread_header(&g_single_once);
if (g_single_once == BeingInitialized) {
Single::Single();
atexit(Single::~Single);
_Init_thread_footer(&g_single_once);
}
}
}
g_single_one는 0으로 초기화
_Init_thread_epoch는 0x80000000으로 초기화
Magic Statics
• 문제는 _Init_thread_epoch가 TLS 변수라는 점!
• Visual Studio 2015에서는 이를 위해 _declspec(thread)를 사용해
암시적 TLS로 처리하는데, Windows XP에서는 암시적 TLS를
정상적으로 지원하지 않아 _Init_thread_epoch가 0으로 초기화됐고,
그러면서 생성도 되지 않은 개체가 생성됐다고 판단이 이루어진 것
Magic Statics
extern "C" void __cdecl _Init_thread_header(int* const pOnce) {
_Init_thread_lock();
if (*pOnce == Uninitialized) {
*pOnce = BeingInitialized;
} else {
while (*pOnce == BeingInitialized)
{
_Init_thread_wait(XpTimeout);
if (*pOnce == Uninitialized) {
*pOnce = BeingInitialized;
_Init_thread_unlock();
return;
}
}
_Init_thread_epoch = _Init_global_epoch;
}
_Init_thread_unlock();
}
Magic Statics
extern "C" void __cdecl _Init_thread_footer(int* const pOnce) {
_Init_thread_lock();
++_Init_global_epoch;
*pOnce = _Init_global_epoch;
_Init_thread_epoch = _Init_global_epoch;
_Init_thread_unlock();
_Init_thread_notify();
}
Magic Statics
• 결론 : Visual Studio 2015에서 프로젝트가 Windows XP를
지원하도록 설정한 경우, Windows XP에서 암시적 TLS를
정상적으로 지원하지 않기 때문에 생기는 문제
• Visual Studio 2015에서는 “Thread-safe Initialization” 옵션이
기본적으로 활성화되어 있음
Magic Statics
• 해결 : 프로젝트 속성에서 C/C++ > Command Line에
“/Zc:threadSafeInit-”를 추가 (비활성화)
Treat Warnings as Errors
• Visual Studio 2015로 오면서 경고를 오류로 취급하는 문제
• C4456 : declaration of ‘x’ hides previous local declaration.
• C4459 : declaration of 'x' hides global declaration.
• C4577 : 'noexcept' used with no exception handling mode specified;
termination on exception is not guaranteed. Specify /EHsc
• C4819 : The file contains a character that cannot be represented in
the current code page (949). Save the file in Unicode format to
prevent data loss.
Treat Warnings as Errors
• 해결 방법 : C/C++ > Advanced의 “Disable Specific Warnings”
에 무시할 경고 번호를 추가하면 됨
마이그레이션 작업 후
Before Merge: Test, test, test it!
• 마이그레이션 작업을 마친 후 프로젝트가 빌드되는지 확인
• 빌드되면 끝? 이제 시작일 뿐!
• 코드 변경으로 인해 기능이 동작하지 않는 경우가 발생할 수 있음
• 또한 코드 변경으로 인해 예상하지 못한 런타임 오류가 발생할 수 있음
• 오랜 시간이 걸리더라도 수행 가능한 범위 내에서 모든 기능을 테스트
• 무엇보다 중요한 것은 라이브 서비스의 안전성!
Code Merge
Migration
저장소
Root
저장소
Root
저장소
After Merge: Test, test, test it again!
• 변경한 코드를 머지한 뒤, 다시 한 번 테스트를 수행
• 기존 프로젝트에서 빌드되고 문제없이 실행되어야 함
또한 마이그레이션한 프로젝트에서도 마찬가지여야 함
• 라이브 서비스로 내보내기 전, 반드시 거쳐야 할 작업!
최대한 많은 인원이 테스트를 할 수 있도록 일정 협의
Visual Studio 2015의 유용한 기능
- Code Analysis
Code Analysis
• Visual Studio 2013, 2015에는 정적 분석 도구가 내장되어 있음
• Analyze > Run Code Analysis 메뉴에서 사용 가능
• 각 프로젝트 속성에서 정적 분석에 사용할 규칙 집합 설정
• Platform Toolset이 “Visual Studio 2015 – Windows XP”인 경우
정적 분석을 할 수 없기 때문에 “Visual Studio 2015”로 변경
• 정적 분석 시간은 프로젝트의 크기에 따라 달라짐
Code Analysis
• 정적 분석을 통해 확인할 수 있는 부분
• NULL 포인터 역참조
• int -> bool 변환
• noexcept 누락
• 부호 불일치
• 지역 변수 / 함수 매개 변수 / 클래스 선언 숨김
• …
Code Analysis
• Demo : 프로젝트의 코드 정적 분석
정리
Summary
Summary
• 마이그레이션 작업 전에 정책 및 계획을 잘 세우시기 바랍니다.
• 마이그레이션 작업은 매우 힘든 작업입니다.
그렇다고 아예 불가능한 작업도 아닙니다.
• 마이그레이션 작업 후에는 최대한 모든 기능을 테스트합시다.
• 뜻이 있는 곳에 길이 있습니다.
• 모든 개발자 분들, 언제나 파이팅입니다!
Special Thanks to
• 마이그레이션 작업은 저 혼자가 아닌 팀에 계신 분들과 함께
진행했습니다. 함께 작업했기에 무사히 마칠 수 있었습니다.
이 자리를 빌어 저희 팀원분들에게 감사하다는 말씀드립니다.
References
• http://www.cppreference.com/
• http://eslife.tistory.com/entry/Visual-Studio-
%EB%B2%84%EC%A0%84-%EB%B3%84-STL-
%EC%A7%80%EC%9B%90
• http://jiniya.net/ng/2016/11/magic-statics/
• https://blogs.msdn.microsoft.com/vcblog/2014/11/12/improve
ments-to-warnings-in-the-c-compiler/
Question?
utilForever@gmail.com
http://fb.com/utilForever
http://www.github.com/utilForever
감사합니다!

Más contenido relacionado

La actualidad más candente

프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법YEONG-CHEON YOU
 
Next-generation MMORPG service architecture
Next-generation MMORPG service architectureNext-generation MMORPG service architecture
Next-generation MMORPG service architectureJongwon Kim
 
전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019
전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019
전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019devCAT Studio, NEXON
 
임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012devCAT Studio, NEXON
 
Multithread & shared_ptr
Multithread & shared_ptrMultithread & shared_ptr
Multithread & shared_ptr내훈 정
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현YEONG-CHEON YOU
 
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012devCAT Studio, NEXON
 
리플렉션과 가비지 컬렉션
리플렉션과 가비지 컬렉션리플렉션과 가비지 컬렉션
리플렉션과 가비지 컬렉션QooJuice
 
그럴듯한 랜덤 생성 컨텐츠 만들기
그럴듯한 랜덤 생성 컨텐츠 만들기그럴듯한 랜덤 생성 컨텐츠 만들기
그럴듯한 랜덤 생성 컨텐츠 만들기Yongha Kim
 
190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁KWANGIL KIM
 
[NDC 2009] 행동 트리로 구현하는 인공지능
[NDC 2009] 행동 트리로 구현하는 인공지능[NDC 2009] 행동 트리로 구현하는 인공지능
[NDC 2009] 행동 트리로 구현하는 인공지능Yongha Kim
 
언리얼을 활용한 오브젝트 풀링
언리얼을 활용한 오브젝트 풀링언리얼을 활용한 오브젝트 풀링
언리얼을 활용한 오브젝트 풀링TonyCms
 
레퍼런스만 알면 언리얼 엔진이 제대로 보인다
레퍼런스만 알면 언리얼 엔진이 제대로 보인다레퍼런스만 알면 언리얼 엔진이 제대로 보인다
레퍼런스만 알면 언리얼 엔진이 제대로 보인다Lee Dustin
 
Multiplayer Game Sync Techniques through CAP theorem
Multiplayer Game Sync Techniques through CAP theoremMultiplayer Game Sync Techniques through CAP theorem
Multiplayer Game Sync Techniques through CAP theoremSeungmo Koo
 
나만의 엔진 개발하기
나만의 엔진 개발하기나만의 엔진 개발하기
나만의 엔진 개발하기YEONG-CHEON YOU
 
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버Heungsub Lee
 
실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략YEONG-CHEON YOU
 
[0903 구경원] recast 네비메쉬
[0903 구경원] recast 네비메쉬[0903 구경원] recast 네비메쉬
[0903 구경원] recast 네비메쉬KyeongWon Koo
 
이무림, Enum의 Boxing을 어찌할꼬? 편리하고 성능좋게 Enum 사용하기, NDC2019
이무림, Enum의 Boxing을 어찌할꼬? 편리하고 성능좋게 Enum 사용하기, NDC2019이무림, Enum의 Boxing을 어찌할꼬? 편리하고 성능좋게 Enum 사용하기, NDC2019
이무림, Enum의 Boxing을 어찌할꼬? 편리하고 성능좋게 Enum 사용하기, NDC2019devCAT Studio, NEXON
 
[NDC2017] 뛰는 프로그래머 나는 언리얼 엔진 - 언알못에서 커미터까지
[NDC2017] 뛰는 프로그래머 나는 언리얼 엔진 - 언알못에서 커미터까지[NDC2017] 뛰는 프로그래머 나는 언리얼 엔진 - 언알못에서 커미터까지
[NDC2017] 뛰는 프로그래머 나는 언리얼 엔진 - 언알못에서 커미터까지Minjung Ko
 

La actualidad más candente (20)

프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
 
Next-generation MMORPG service architecture
Next-generation MMORPG service architectureNext-generation MMORPG service architecture
Next-generation MMORPG service architecture
 
전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019
전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019
전형규, SilvervineUE4Lua: UE4에서 Lua 사용하기, NDC2019
 
임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012
 
Multithread & shared_ptr
Multithread & shared_ptrMultithread & shared_ptr
Multithread & shared_ptr
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현
 
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
 
리플렉션과 가비지 컬렉션
리플렉션과 가비지 컬렉션리플렉션과 가비지 컬렉션
리플렉션과 가비지 컬렉션
 
그럴듯한 랜덤 생성 컨텐츠 만들기
그럴듯한 랜덤 생성 컨텐츠 만들기그럴듯한 랜덤 생성 컨텐츠 만들기
그럴듯한 랜덤 생성 컨텐츠 만들기
 
190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁
 
[NDC 2009] 행동 트리로 구현하는 인공지능
[NDC 2009] 행동 트리로 구현하는 인공지능[NDC 2009] 행동 트리로 구현하는 인공지능
[NDC 2009] 행동 트리로 구현하는 인공지능
 
언리얼을 활용한 오브젝트 풀링
언리얼을 활용한 오브젝트 풀링언리얼을 활용한 오브젝트 풀링
언리얼을 활용한 오브젝트 풀링
 
레퍼런스만 알면 언리얼 엔진이 제대로 보인다
레퍼런스만 알면 언리얼 엔진이 제대로 보인다레퍼런스만 알면 언리얼 엔진이 제대로 보인다
레퍼런스만 알면 언리얼 엔진이 제대로 보인다
 
Multiplayer Game Sync Techniques through CAP theorem
Multiplayer Game Sync Techniques through CAP theoremMultiplayer Game Sync Techniques through CAP theorem
Multiplayer Game Sync Techniques through CAP theorem
 
나만의 엔진 개발하기
나만의 엔진 개발하기나만의 엔진 개발하기
나만의 엔진 개발하기
 
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
 
실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략
 
[0903 구경원] recast 네비메쉬
[0903 구경원] recast 네비메쉬[0903 구경원] recast 네비메쉬
[0903 구경원] recast 네비메쉬
 
이무림, Enum의 Boxing을 어찌할꼬? 편리하고 성능좋게 Enum 사용하기, NDC2019
이무림, Enum의 Boxing을 어찌할꼬? 편리하고 성능좋게 Enum 사용하기, NDC2019이무림, Enum의 Boxing을 어찌할꼬? 편리하고 성능좋게 Enum 사용하기, NDC2019
이무림, Enum의 Boxing을 어찌할꼬? 편리하고 성능좋게 Enum 사용하기, NDC2019
 
[NDC2017] 뛰는 프로그래머 나는 언리얼 엔진 - 언알못에서 커미터까지
[NDC2017] 뛰는 프로그래머 나는 언리얼 엔진 - 언알못에서 커미터까지[NDC2017] 뛰는 프로그래머 나는 언리얼 엔진 - 언알못에서 커미터까지
[NDC2017] 뛰는 프로그래머 나는 언리얼 엔진 - 언알못에서 커미터까지
 

Destacado

[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features Summary[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features SummaryChris Ohk
 
1인개발자가되기전알아야할것들
1인개발자가되기전알아야할것들1인개발자가되기전알아야할것들
1인개발자가되기전알아야할것들Jinsub Jung
 
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback흥배 최
 
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기Chris Ohk
 
[제1회 시나브로 그룹 오프라인 밋업] 개발자의 자존감
[제1회 시나브로 그룹 오프라인 밋업] 개발자의 자존감[제1회 시나브로 그룹 오프라인 밋업] 개발자의 자존감
[제1회 시나브로 그룹 오프라인 밋업] 개발자의 자존감Chris Ohk
 
Data Structure - 1st Study
Data Structure - 1st StudyData Structure - 1st Study
Data Structure - 1st StudyChris Ohk
 
게임 프로그래밍 기초 공부법
게임 프로그래밍 기초 공부법게임 프로그래밍 기초 공부법
게임 프로그래밍 기초 공부법Chris Ohk
 
C++ Programming - 14th Study
C++ Programming - 14th StudyC++ Programming - 14th Study
C++ Programming - 14th StudyChris Ohk
 
NDC 2015. 한 그루 한 그루 심지 않아도 돼요. 생태학에 기반한 [야생의 땅: 듀랑고]의 절차적 생성 생태계
NDC 2015. 한 그루 한 그루 심지 않아도 돼요. 생태학에 기반한 [야생의 땅: 듀랑고]의 절차적 생성 생태계NDC 2015. 한 그루 한 그루 심지 않아도 돼요. 생태학에 기반한 [야생의 땅: 듀랑고]의 절차적 생성 생태계
NDC 2015. 한 그루 한 그루 심지 않아도 돼요. 생태학에 기반한 [야생의 땅: 듀랑고]의 절차적 생성 생태계Imseong Kang
 
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현유니티의 툰셰이딩을 사용한 3D 애니메이션 표현
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현MinGeun Park
 
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30Chris Ohk
 
C++ Programming - 11th Study
C++ Programming - 11th StudyC++ Programming - 11th Study
C++ Programming - 11th StudyChris Ohk
 
Data Structure - 2nd Study
Data Structure - 2nd StudyData Structure - 2nd Study
Data Structure - 2nd StudyChris Ohk
 
[NHN_NEXT] DirectX Tutorial 강의 자료
[NHN_NEXT] DirectX Tutorial 강의 자료[NHN_NEXT] DirectX Tutorial 강의 자료
[NHN_NEXT] DirectX Tutorial 강의 자료MinGeun Park
 
도톰치게임즈 1인개발
도톰치게임즈 1인개발도톰치게임즈 1인개발
도톰치게임즈 1인개발Seok Kyu Chang
 
고대특강 게임 프로그래머의 소양
고대특강   게임 프로그래머의 소양고대특강   게임 프로그래머의 소양
고대특강 게임 프로그래머의 소양Jubok Kim
 
[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)
[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)
[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)Sang Don Kim
 
게임 프레임워크의 아키텍쳐와 디자인 패턴
게임 프레임워크의 아키텍쳐와 디자인 패턴게임 프레임워크의 아키텍쳐와 디자인 패턴
게임 프레임워크의 아키텍쳐와 디자인 패턴MinGeun Park
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심흥배 최
 
[C++ Korea] Effective Modern C++ Study, Item 11 - 13
[C++ Korea] Effective Modern C++ Study, Item 11 - 13[C++ Korea] Effective Modern C++ Study, Item 11 - 13
[C++ Korea] Effective Modern C++ Study, Item 11 - 13Chris Ohk
 

Destacado (20)

[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features Summary[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features Summary
 
1인개발자가되기전알아야할것들
1인개발자가되기전알아야할것들1인개발자가되기전알아야할것들
1인개발자가되기전알아야할것들
 
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
 
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
 
[제1회 시나브로 그룹 오프라인 밋업] 개발자의 자존감
[제1회 시나브로 그룹 오프라인 밋업] 개발자의 자존감[제1회 시나브로 그룹 오프라인 밋업] 개발자의 자존감
[제1회 시나브로 그룹 오프라인 밋업] 개발자의 자존감
 
Data Structure - 1st Study
Data Structure - 1st StudyData Structure - 1st Study
Data Structure - 1st Study
 
게임 프로그래밍 기초 공부법
게임 프로그래밍 기초 공부법게임 프로그래밍 기초 공부법
게임 프로그래밍 기초 공부법
 
C++ Programming - 14th Study
C++ Programming - 14th StudyC++ Programming - 14th Study
C++ Programming - 14th Study
 
NDC 2015. 한 그루 한 그루 심지 않아도 돼요. 생태학에 기반한 [야생의 땅: 듀랑고]의 절차적 생성 생태계
NDC 2015. 한 그루 한 그루 심지 않아도 돼요. 생태학에 기반한 [야생의 땅: 듀랑고]의 절차적 생성 생태계NDC 2015. 한 그루 한 그루 심지 않아도 돼요. 생태학에 기반한 [야생의 땅: 듀랑고]의 절차적 생성 생태계
NDC 2015. 한 그루 한 그루 심지 않아도 돼요. 생태학에 기반한 [야생의 땅: 듀랑고]의 절차적 생성 생태계
 
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현유니티의 툰셰이딩을 사용한 3D 애니메이션 표현
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현
 
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
 
C++ Programming - 11th Study
C++ Programming - 11th StudyC++ Programming - 11th Study
C++ Programming - 11th Study
 
Data Structure - 2nd Study
Data Structure - 2nd StudyData Structure - 2nd Study
Data Structure - 2nd Study
 
[NHN_NEXT] DirectX Tutorial 강의 자료
[NHN_NEXT] DirectX Tutorial 강의 자료[NHN_NEXT] DirectX Tutorial 강의 자료
[NHN_NEXT] DirectX Tutorial 강의 자료
 
도톰치게임즈 1인개발
도톰치게임즈 1인개발도톰치게임즈 1인개발
도톰치게임즈 1인개발
 
고대특강 게임 프로그래머의 소양
고대특강   게임 프로그래머의 소양고대특강   게임 프로그래머의 소양
고대특강 게임 프로그래머의 소양
 
[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)
[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)
[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)
 
게임 프레임워크의 아키텍쳐와 디자인 패턴
게임 프레임워크의 아키텍쳐와 디자인 패턴게임 프레임워크의 아키텍쳐와 디자인 패턴
게임 프레임워크의 아키텍쳐와 디자인 패턴
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심
 
[C++ Korea] Effective Modern C++ Study, Item 11 - 13
[C++ Korea] Effective Modern C++ Study, Item 11 - 13[C++ Korea] Effective Modern C++ Study, Item 11 - 13
[C++ Korea] Effective Modern C++ Study, Item 11 - 13
 

Similar a [C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기

청강대 특강 - 프로젝트 제대로 해보기
청강대 특강 - 프로젝트 제대로 해보기청강대 특강 - 프로젝트 제대로 해보기
청강대 특강 - 프로젝트 제대로 해보기Chris Ohk
 
안드로이드 오픈소스 어플리케이션 블록
안드로이드 오픈소스 어플리케이션 블록안드로이드 오픈소스 어플리케이션 블록
안드로이드 오픈소스 어플리케이션 블록YoungSu Son
 
[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...
[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...
[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...Taekyu Lim
 
머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발
머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발
머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발Jeongkyu Shin
 
[122]네이버의모던웹라이브러리 박재성
[122]네이버의모던웹라이브러리 박재성[122]네이버의모던웹라이브러리 박재성
[122]네이버의모던웹라이브러리 박재성NAVER D2
 
[야생의 땅: 듀랑고] 지형 관리 완전 자동화 - 생생한 AWS와 Docker 체험기
[야생의 땅: 듀랑고] 지형 관리 완전 자동화 - 생생한 AWS와 Docker 체험기[야생의 땅: 듀랑고] 지형 관리 완전 자동화 - 생생한 AWS와 Docker 체험기
[야생의 땅: 듀랑고] 지형 관리 완전 자동화 - 생생한 AWS와 Docker 체험기Sumin Byeon
 
2020년 11월 14일 개발자 이야기
2020년 11월 14일 개발자 이야기2020년 11월 14일 개발자 이야기
2020년 11월 14일 개발자 이야기Jay Park
 
C++ GUI 라이브러리 소개: Qt & Nana
C++ GUI 라이브러리 소개: Qt & NanaC++ GUI 라이브러리 소개: Qt & Nana
C++ GUI 라이브러리 소개: Qt & NanaLazy Ahasil
 
Angular는 사실 어렵지 않습니다.
Angular는 사실 어렵지 않습니다.Angular는 사실 어렵지 않습니다.
Angular는 사실 어렵지 않습니다.장현 한
 
아키텍트가 알아야 할 12/97가지
아키텍트가 알아야 할 12/97가지아키텍트가 알아야 할 12/97가지
아키텍트가 알아야 할 12/97가지YoungSu Son
 
S#03 김용현:VS2010으로 마이그레이션
S#03 김용현:VS2010으로 마이그레이션S#03 김용현:VS2010으로 마이그레이션
S#03 김용현:VS2010으로 마이그레이션codercay
 
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013devCAT Studio, NEXON
 
초보 개발자/학생들을 위한 오픈소스 트랜드
초보 개발자/학생들을 위한 오픈소스 트랜드 초보 개발자/학생들을 위한 오픈소스 트랜드
초보 개발자/학생들을 위한 오픈소스 트랜드 YoungSu Son
 
객체지향프로그래밍 특강
객체지향프로그래밍 특강객체지향프로그래밍 특강
객체지향프로그래밍 특강uEngine Solutions
 
OpenJigWare(V02.00.04)
OpenJigWare(V02.00.04)OpenJigWare(V02.00.04)
OpenJigWare(V02.00.04)Jinwook On
 
이클립스 플랫폼
이클립스 플랫폼이클립스 플랫폼
이클립스 플랫폼Kenu, GwangNam Heo
 
NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁
NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁
NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁Yi-kwon Hwang
 

Similar a [C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기 (20)

청강대 특강 - 프로젝트 제대로 해보기
청강대 특강 - 프로젝트 제대로 해보기청강대 특강 - 프로젝트 제대로 해보기
청강대 특강 - 프로젝트 제대로 해보기
 
안드로이드 오픈소스 어플리케이션 블록
안드로이드 오픈소스 어플리케이션 블록안드로이드 오픈소스 어플리케이션 블록
안드로이드 오픈소스 어플리케이션 블록
 
[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...
[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...
[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...
 
머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발
머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발
머신러닝 및 데이터 과학 연구자를 위한 python 기반 컨테이너 분산처리 플랫폼 설계 및 개발
 
Open Jig Ware
Open Jig WareOpen Jig Ware
Open Jig Ware
 
[122]네이버의모던웹라이브러리 박재성
[122]네이버의모던웹라이브러리 박재성[122]네이버의모던웹라이브러리 박재성
[122]네이버의모던웹라이브러리 박재성
 
[야생의 땅: 듀랑고] 지형 관리 완전 자동화 - 생생한 AWS와 Docker 체험기
[야생의 땅: 듀랑고] 지형 관리 완전 자동화 - 생생한 AWS와 Docker 체험기[야생의 땅: 듀랑고] 지형 관리 완전 자동화 - 생생한 AWS와 Docker 체험기
[야생의 땅: 듀랑고] 지형 관리 완전 자동화 - 생생한 AWS와 Docker 체험기
 
2020년 11월 14일 개발자 이야기
2020년 11월 14일 개발자 이야기2020년 11월 14일 개발자 이야기
2020년 11월 14일 개발자 이야기
 
C++ GUI 라이브러리 소개: Qt & Nana
C++ GUI 라이브러리 소개: Qt & NanaC++ GUI 라이브러리 소개: Qt & Nana
C++ GUI 라이브러리 소개: Qt & Nana
 
Angular는 사실 어렵지 않습니다.
Angular는 사실 어렵지 않습니다.Angular는 사실 어렵지 않습니다.
Angular는 사실 어렵지 않습니다.
 
아키텍트가 알아야 할 12/97가지
아키텍트가 알아야 할 12/97가지아키텍트가 알아야 할 12/97가지
아키텍트가 알아야 할 12/97가지
 
S#03 김용현:VS2010으로 마이그레이션
S#03 김용현:VS2010으로 마이그레이션S#03 김용현:VS2010으로 마이그레이션
S#03 김용현:VS2010으로 마이그레이션
 
Meteor IoT
Meteor IoTMeteor IoT
Meteor IoT
 
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
 
초보 개발자/학생들을 위한 오픈소스 트랜드
초보 개발자/학생들을 위한 오픈소스 트랜드 초보 개발자/학생들을 위한 오픈소스 트랜드
초보 개발자/학생들을 위한 오픈소스 트랜드
 
객체지향프로그래밍 특강
객체지향프로그래밍 특강객체지향프로그래밍 특강
객체지향프로그래밍 특강
 
OpenJigWare(V02.00.04)
OpenJigWare(V02.00.04)OpenJigWare(V02.00.04)
OpenJigWare(V02.00.04)
 
이클립스 플랫폼
이클립스 플랫폼이클립스 플랫폼
이클립스 플랫폼
 
NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁
NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁
NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁
 
쉽고 빠르게 접하는 오픈스택
쉽고 빠르게 접하는 오픈스택쉽고 빠르게 접하는 오픈스택
쉽고 빠르게 접하는 오픈스택
 

Más de Chris Ohk

인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍Chris Ohk
 
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들Chris Ohk
 
Momenti Seminar - 5 Years of RosettaStone
Momenti Seminar - 5 Years of RosettaStoneMomenti Seminar - 5 Years of RosettaStone
Momenti Seminar - 5 Years of RosettaStoneChris Ohk
 
선린인터넷고등학교 2021 알고리즘 컨퍼런스 - Rust로 알고리즘 문제 풀어보기
선린인터넷고등학교 2021 알고리즘 컨퍼런스 - Rust로 알고리즘 문제 풀어보기선린인터넷고등학교 2021 알고리즘 컨퍼런스 - Rust로 알고리즘 문제 풀어보기
선린인터넷고등학교 2021 알고리즘 컨퍼런스 - Rust로 알고리즘 문제 풀어보기Chris Ohk
 
Momenti Seminar - A Tour of Rust, Part 2
Momenti Seminar - A Tour of Rust, Part 2Momenti Seminar - A Tour of Rust, Part 2
Momenti Seminar - A Tour of Rust, Part 2Chris Ohk
 
Momenti Seminar - A Tour of Rust, Part 1
Momenti Seminar - A Tour of Rust, Part 1Momenti Seminar - A Tour of Rust, Part 1
Momenti Seminar - A Tour of Rust, Part 1Chris Ohk
 
Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021
Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021
Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021Chris Ohk
 
Adversarially Guided Actor-Critic, Y. Flet-Berliac et al, 2021
Adversarially Guided Actor-Critic, Y. Flet-Berliac et al, 2021Adversarially Guided Actor-Critic, Y. Flet-Berliac et al, 2021
Adversarially Guided Actor-Critic, Y. Flet-Berliac et al, 2021Chris Ohk
 
Agent57: Outperforming the Atari Human Benchmark, Badia, A. P. et al, 2020
Agent57: Outperforming the Atari Human Benchmark, Badia, A. P. et al, 2020Agent57: Outperforming the Atari Human Benchmark, Badia, A. P. et al, 2020
Agent57: Outperforming the Atari Human Benchmark, Badia, A. P. et al, 2020Chris Ohk
 
Proximal Policy Optimization Algorithms, Schulman et al, 2017
Proximal Policy Optimization Algorithms, Schulman et al, 2017Proximal Policy Optimization Algorithms, Schulman et al, 2017
Proximal Policy Optimization Algorithms, Schulman et al, 2017Chris Ohk
 
Trust Region Policy Optimization, Schulman et al, 2015
Trust Region Policy Optimization, Schulman et al, 2015Trust Region Policy Optimization, Schulman et al, 2015
Trust Region Policy Optimization, Schulman et al, 2015Chris Ohk
 
Continuous Control with Deep Reinforcement Learning, lillicrap et al, 2015
Continuous Control with Deep Reinforcement Learning, lillicrap et al, 2015Continuous Control with Deep Reinforcement Learning, lillicrap et al, 2015
Continuous Control with Deep Reinforcement Learning, lillicrap et al, 2015Chris Ohk
 
GDG Gwangju DevFest 2019 - <하스스톤> 강화학습 환경 개발기
GDG Gwangju DevFest 2019 - <하스스톤> 강화학습 환경 개발기GDG Gwangju DevFest 2019 - <하스스톤> 강화학습 환경 개발기
GDG Gwangju DevFest 2019 - <하스스톤> 강화학습 환경 개발기Chris Ohk
 
[RLKorea] <하스스톤> 강화학습 환경 개발기
[RLKorea] <하스스톤> 강화학습 환경 개발기[RLKorea] <하스스톤> 강화학습 환경 개발기
[RLKorea] <하스스톤> 강화학습 환경 개발기Chris Ohk
 
[NDC 2019] 하스스톤 강화학습 환경 개발기
[NDC 2019] 하스스톤 강화학습 환경 개발기[NDC 2019] 하스스톤 강화학습 환경 개발기
[NDC 2019] 하스스톤 강화학습 환경 개발기Chris Ohk
 
C++20 Key Features Summary
C++20 Key Features SummaryC++20 Key Features Summary
C++20 Key Features SummaryChris Ohk
 
[델리만주] 대학원 캐슬 - 석사에서 게임 프로그래머까지
[델리만주] 대학원 캐슬 - 석사에서 게임 프로그래머까지[델리만주] 대학원 캐슬 - 석사에서 게임 프로그래머까지
[델리만주] 대학원 캐슬 - 석사에서 게임 프로그래머까지Chris Ohk
 
디미고 특강 - 개발을 시작하려는 여러분에게
디미고 특강 - 개발을 시작하려는 여러분에게디미고 특강 - 개발을 시작하려는 여러분에게
디미고 특강 - 개발을 시작하려는 여러분에게Chris Ohk
 
[NDC 2018] 유체역학 엔진 개발기
[NDC 2018] 유체역학 엔진 개발기[NDC 2018] 유체역학 엔진 개발기
[NDC 2018] 유체역학 엔진 개발기Chris Ohk
 
My Way, Your Way
My Way, Your WayMy Way, Your Way
My Way, Your WayChris Ohk
 

Más de Chris Ohk (20)

인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
 
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
 
Momenti Seminar - 5 Years of RosettaStone
Momenti Seminar - 5 Years of RosettaStoneMomenti Seminar - 5 Years of RosettaStone
Momenti Seminar - 5 Years of RosettaStone
 
선린인터넷고등학교 2021 알고리즘 컨퍼런스 - Rust로 알고리즘 문제 풀어보기
선린인터넷고등학교 2021 알고리즘 컨퍼런스 - Rust로 알고리즘 문제 풀어보기선린인터넷고등학교 2021 알고리즘 컨퍼런스 - Rust로 알고리즘 문제 풀어보기
선린인터넷고등학교 2021 알고리즘 컨퍼런스 - Rust로 알고리즘 문제 풀어보기
 
Momenti Seminar - A Tour of Rust, Part 2
Momenti Seminar - A Tour of Rust, Part 2Momenti Seminar - A Tour of Rust, Part 2
Momenti Seminar - A Tour of Rust, Part 2
 
Momenti Seminar - A Tour of Rust, Part 1
Momenti Seminar - A Tour of Rust, Part 1Momenti Seminar - A Tour of Rust, Part 1
Momenti Seminar - A Tour of Rust, Part 1
 
Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021
Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021
Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021
 
Adversarially Guided Actor-Critic, Y. Flet-Berliac et al, 2021
Adversarially Guided Actor-Critic, Y. Flet-Berliac et al, 2021Adversarially Guided Actor-Critic, Y. Flet-Berliac et al, 2021
Adversarially Guided Actor-Critic, Y. Flet-Berliac et al, 2021
 
Agent57: Outperforming the Atari Human Benchmark, Badia, A. P. et al, 2020
Agent57: Outperforming the Atari Human Benchmark, Badia, A. P. et al, 2020Agent57: Outperforming the Atari Human Benchmark, Badia, A. P. et al, 2020
Agent57: Outperforming the Atari Human Benchmark, Badia, A. P. et al, 2020
 
Proximal Policy Optimization Algorithms, Schulman et al, 2017
Proximal Policy Optimization Algorithms, Schulman et al, 2017Proximal Policy Optimization Algorithms, Schulman et al, 2017
Proximal Policy Optimization Algorithms, Schulman et al, 2017
 
Trust Region Policy Optimization, Schulman et al, 2015
Trust Region Policy Optimization, Schulman et al, 2015Trust Region Policy Optimization, Schulman et al, 2015
Trust Region Policy Optimization, Schulman et al, 2015
 
Continuous Control with Deep Reinforcement Learning, lillicrap et al, 2015
Continuous Control with Deep Reinforcement Learning, lillicrap et al, 2015Continuous Control with Deep Reinforcement Learning, lillicrap et al, 2015
Continuous Control with Deep Reinforcement Learning, lillicrap et al, 2015
 
GDG Gwangju DevFest 2019 - <하스스톤> 강화학습 환경 개발기
GDG Gwangju DevFest 2019 - <하스스톤> 강화학습 환경 개발기GDG Gwangju DevFest 2019 - <하스스톤> 강화학습 환경 개발기
GDG Gwangju DevFest 2019 - <하스스톤> 강화학습 환경 개발기
 
[RLKorea] <하스스톤> 강화학습 환경 개발기
[RLKorea] <하스스톤> 강화학습 환경 개발기[RLKorea] <하스스톤> 강화학습 환경 개발기
[RLKorea] <하스스톤> 강화학습 환경 개발기
 
[NDC 2019] 하스스톤 강화학습 환경 개발기
[NDC 2019] 하스스톤 강화학습 환경 개발기[NDC 2019] 하스스톤 강화학습 환경 개발기
[NDC 2019] 하스스톤 강화학습 환경 개발기
 
C++20 Key Features Summary
C++20 Key Features SummaryC++20 Key Features Summary
C++20 Key Features Summary
 
[델리만주] 대학원 캐슬 - 석사에서 게임 프로그래머까지
[델리만주] 대학원 캐슬 - 석사에서 게임 프로그래머까지[델리만주] 대학원 캐슬 - 석사에서 게임 프로그래머까지
[델리만주] 대학원 캐슬 - 석사에서 게임 프로그래머까지
 
디미고 특강 - 개발을 시작하려는 여러분에게
디미고 특강 - 개발을 시작하려는 여러분에게디미고 특강 - 개발을 시작하려는 여러분에게
디미고 특강 - 개발을 시작하려는 여러분에게
 
[NDC 2018] 유체역학 엔진 개발기
[NDC 2018] 유체역학 엔진 개발기[NDC 2018] 유체역학 엔진 개발기
[NDC 2018] 유체역학 엔진 개발기
 
My Way, Your Way
My Way, Your WayMy Way, Your Way
My Way, Your Way
 

[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기

  • 1. 옥찬호 / Nexon Korea, C++ Korea 새 C++은 새 Visual Studio에? - 좌충우돌 마이그레이션 이야기
  • 2. 소개 • 옥찬호 (Chris Ohk) • Nexon Korea Game Programmer • Microsoft Visual C++ MVP • 페이스북 그룹 C++ Korea 대표 • IT 전문서 집필 및 번역 다수 • 게임샐러드로 코드 한 줄 없이 게임 만들기 (2013) • 유니티 Shader와 Effect 제작 (2014) • 2D 게임 프로그래밍 (2014) • 러스트 핵심 노트 (2017) • ing…
  • 3. 시작하기 전에… • 현재 서비스 중인 프로젝트를 Visual Studio 2008에서 Visual Studio 2015로 마이그레이션하면서 겪었던 문제들과 해결 방안에 대해 설명합니다. • 마이그레이션을 하면서 겪었던 문제 중 공유드릴만한 내용을 간추려서 설명합니다. • 마이그레이션을 하면서 겪게 되는 문제와 해결 방안은 프로젝트마다 다를 수 있음을 참고해주시기 바랍니다.
  • 4. What is project migration? 하나의 시스템, 플랫폼, 애플리케이션, 위치 또는 인프라 집합에 서 하나 이상의 프로젝트 관련 항목을 다른 곳으로 옮기는 것과 연관된 프로세스 및 프로젝트 작업 https://www.if4it.com/SYNTHESIZED/GLOSSARY/P/Project_Migration.html
  • 5. Statistics of project migration in 2015 66% of IT pros delayed a migration due to past experience. 44% experienced a migration failure in 2015 75% of companies that performed a migration in 2015 were offline for 48 hours or longer http://www.itworld.co.kr/print/101274
  • 6. Difficulties of project migration • 일정 관리 문제 – 프로젝트 진행 기간을 산출하기 어려움 • 종속성 문제 – 최신 버전에 대한 라이브러리 미지원 • 안전성 문제 – 라이브 서비스에 문제가 생길 수도 있다는 불안 • 관리 문제 – 라이브 서비스 컨텐츠 개발과 동시에 진행해야 함 • 인력 문제 – 마이그레이션 작업을 담당할 사람이 부족함 • …
  • 9. Table of Contents • 마이그레이션 작업 전 • 마이그레이션 작업 • 마이그레이션 작업 후 • Visual Studio 2015의 유용한 기능 - Code Analysis • 정리
  • 11. Library Check • 프로젝트에 종속되어 있는 라이브러리가 마이그레이션할 Visual Studio 버전을 지원하는지 확인 • 지원하는 경우, 해당 버전의 라이브러리 파일 다운로드 (32 / 64비트 주의) • 지원하지 않는 경우, 대체 가능한 라이브러리 찾아보기 • 상용 라이브러리의 경우, 해당 버전의 라이브러리 지원 여부에 따라 비용이 들어갈 수도 있으므로 반드시 확인해야 함 • 비용이 너무 많이 들 경우, 포기해야 될 수도 있음
  • 12. Migration Policy • Output 폴더와 Library 폴더에 대한 정책 수립 • Output 폴더 정리 • 중간 파일 사용 여부 • 배치 파일 템플릿 작성 • Library 폴더 정리 • 프로젝트에서 사용하지 않는 라이브러리 확인 • 사용하지 않는 라이브러리에 대해 마크 표시한 뒤 차후에 삭제
  • 13. Fork Branch • 고려해야 할 사항 • 라이브 서비스 중인 프로젝트에 영향이 생겨서는 안 됨 • 마이그레이션 작업 후 모든 기능에 이상이 없는지 검사한 뒤, 문제가 없을 경우에만 새로운 프로젝트에서 작업해야 함 • 수정하는 코드가 많은 경우, 다른 기능에 영향을 줄 수 있기에 가능한 오랜 시간 동안 검증할 수 있어야 함 (프로그램 안전성↑)
  • 15. Note • Visual Studio 2015 설치 시 Windows 8.1 SDK 및 유니버셜 CRT SDK 설치 필요 (Community 버전 기준으로 기본 설치됨) • afxres.h 파일이 없어 빌드 오류가 발생하면 winresrc.h로 대체 • 상속 속성 페이지 파일 확장자가 .vcprops에서 .props로 변경됨 • 프로젝트에서 필터를 관리하는 파일 확장자 추가 : .filters • 프로젝트 파일 확장자가 .vcproj에서 .vcxproj로 변경됨
  • 17. STLport • C++ 표준 라이브러리의 포터블 버전 • 1997년 1월, Boris Fomitchev가 개발 시작 • 상용 프로그램에서도 무료로 사용 가능 • 2008년 12월 10일, 마지막 버전 릴리즈 (5.2.1) • 구버전의 Visual Studio 프로젝트에서 많이 사용
  • 20. Why use STLport? • 사례 1 : std::vector std::vector<std::string> data; data.push_back("abc"); data.push_back("123"); data.push_back("가나다"); warning C4786: 'std::reverse_iterator<std::basic_string<char,std::char_ traits<char>,std::allocator<char>> const*, std::basic_string<char,std::char_traits<char>, std::allocator<char> >,std::basic_string<char, std::char_traits<char>,std::allocator<char> > const &, std::basic_string<char,std::char_traits<char>, std::allocator<char> > const *,int>' : identifier was truncated to ‘255’ characters in the debug information
  • 21. Why use STLport? • 사례 2 : std::map std::map<std::string, std::string> data; data.insert(std::make_pair("123", "숫자")); data.insert(std::make_pair("가나다", "한글")); std::map<std::string, std::string> data; data.insert(std::make_pair(std::string("123"), std::string("숫자")); // OK data.insert(std::make_pair(std::string("가나다"), std::string("한글")); // OK // Error // Error
  • 23. Why use STLport? • 구버전의 Visual Studio에서 STL 지원과 관련된 많은 문제 발생 • 따라서 가볍고 보다 안정적인 STLport를 사용하게 됨 • 하지만 Visual Studio 2005를 기점으로 STL 지원과 관련된 문제들은 거의 발생하지 않음 • Visual Studio 최신 버전에서는 벡터 병렬 계산 등이 도입되면서 속도 측면에서도 많이 개선됨 → 바꾸지 않을 이유가 없다!
  • 24. STLPort Removal • 이제 제거해 봅시다.
  • 27. STLPort Removal • 오류의 원인 1 : STLPort에는 있는데, STL에는 없는 자료구조 • hash_map (https://www.sgi.com/tech/stl/hash_map.html) • hash_set (https://www.sgi.com/tech/stl/hash_set.html) #include <hash_set> typedef std::hash_set<DWORD> CHashSet; #include <hash_map> typedef std::hash_map<DWORD> CHashMap;
  • 28. STLPort Removal • 해결 방법 • hash_map은 unordered_map으로 변경 • hash_set은 unordered_set으로 변경 //#include <hash_set> //typedef std::hash_set<DWORD> CHashSet; #include <unordered_set> typedef std::unordered_set<DWORD> CHashSet; //#include <hash_map> //typedef std::hash_map<DWORD> CHashMap; #include <unordered_map> typedef std::unordered_map<DWORD> CHashMap;
  • 29. #if (_MSC_VER >= 1900) #include <unordered_set> typedef std::unordered_set<DWORD> CHashSet; #include <unordered_map> typedef std::unordered_map<DWORD> CHashMap; #else #include <hash_set> typedef std::hash_set<DWORD> CHashSet; #include <hash_map> typedef std::hash_map<DWORD> CHashMap; #endif STLPort Removal • 참고 사항 : 기존 프로젝트와 충돌이 나지 않도록 전처리
  • 30. STLPort Removal • 오류의 원인 2 : push_back() • STLPort에서는 매개 변수 없는 push_back()을 허용 struct Data { double weight; double height; }; std::vector<Data> data; int index = -1; // Add Data data.push_back(); index++; data[index].weight = 60.0; data[index].height = 180.0;
  • 31. STLPort Removal • 해결 방법 • 변수를 하나 선언한 뒤, 데이터를 채우고 push_back() // Add Data //data.push_back(); //index++; //data[index].weight = 60.0; //data[index].height = 180.0; Data tempData; tempData.weight = 60.0; tempData.height = 180.0; data.push_back(tempData);
  • 32. void func(const char* str) { if (str && *str) { int size = strlen(str); std::string::const_iterator begin = str; std::string::const_iterator end = begin + size; ... } } STLPort Removal • 오류의 원인 3 : 포인터 기반 반복자 • STLPort의 const_iterator는 const char*
  • 33. STLPort Removal • 해결 방법 • const_iterator를 표준 반복자로 변환 void func(const char* str) { if (str && *str) { std::string text(str); std::string::const_iterator begin = text.cbegin(); std::string::const_iterator end = text.cend(); ... } }
  • 34. STLPort Removal • 참고 사항 : 기존 프로젝트와 충돌이 나지 않도록 전처리 (STLPort는 cbegin, cend 함수를 지원하지 않음) #if (_MSC_VER >= 1900) std::string::const_iterator itbegin = token.cbegin(); std::string::const_iterator itend = token.cend(); #else std::string::const_iterator itbegin = token.begin(); std::string::const_iterator itend = token.end(); #endif
  • 35. STLPort Removal • 종속 관계를 갖는 프로젝트가 많은 경우, STLPort를 제거해도 포함된 .lib나 .dll로 인해 완전히 제거되지 않는 경우가 있음
  • 36. STLPort Removal • 해결 방법 : 프로젝트 종속 관계를 파악한 뒤, 풀어나간다.
  • 37. STLPort Removal • 주의 : 실타래를 풀다가 지칠 수도 있으니 숨을 쉬어가면서 하자.
  • 38. STL Function Change • 경우 1 : round() 함수 변화 • C99 • C++11 double round(double x); float roundf(float x); long double roundl(long double x); double round(double x); float round(float x); long double round(long double x); double round(T x); // additional overloads for integral types
  • 39. STL Function Change • 경우 2 : 곧 없어지는 auto_ptr (C++17에서 없어질 예정) • unique_ptr • shared_ptr • weak_ptr std::unique_ptr<Data> pUnique; auto pUnique2 = std::make_unique<Data>(); std::shared_ptr<Data> pShared; auto pShared2 = std::make_shared<Data>(); std::weak_ptr<Data> pWeak; auto pWeak2 = pShared;
  • 40. Macro Change • 경우 1 : 매크로 / 매크로 함수 구분 #define DECLARE_FUNCTION #define DECLARE_FUNCTION_() class Test { DECLARE_FUNCTION(); // Error DECLARE_FUNCTION_(); // OK };
  • 41. Macro Change • 경우 2 : 매크로 문자열 사용 시 구분을 위한 공백 필요 #define MACROSTR "STRING MACRO" const char* ERROR = "error"MACROSTR "error"; // Error const char* VALID = "valid" MACROSTR "error"; // OK
  • 42. Windows XP Support • Visual Studio 최신 버전에서는 기본적으로 Windows XP를 지원하지 않음 → Windows XP를 지원하는 프로그램에서 문제! • 해결 방법 : 프로젝트 속성에서 “Platform Toolset”을 “Visual Studio 2015”에서 “Visual Studio 2015 – Windows XP”로 변경
  • 43. Magic Statics • 다음과 같은 클래스가 있다고 하자 class Single { private: Single() { std::cout << "Constructorn"; } public: ~Single() { std::cout << "Destructorn"; } static Single& Instance() { static Single s; return s; } };
  • 44. Magic Statics • Visual Studio 2015에서 프로젝트를 빌드한 뒤 실행할 때 싱글턴 패턴으로 구현한 클래스 타입에 대한 인스턴스를 static으로 정의할 경우 Lock이 걸린 뒤 풀리지 않아 무한 루프에 빠지는 현상이 발생
  • 45. Magic Statics • 원인 : C++11부터 지역 static 개체 생성이 스레드 안전하게 보 장하도록 표준에 추가됨 → 이를 “Magic Statics”라고 함 (https://msdn.microsoft.com/en-us/library/hh567368.aspx) • Magic Statics에 대한 자세한 내용은 C++11 표준 문서 참조 “Dynamic Initialization and Destruction with Concurrency” (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm)
  • 46. Magic Statics • Visual Studio 2015가 static 지역 개체 초기화를 스레드 안전하게 하기 위해서 사용하는 전략 - Lock과 TLS(Thread Local Storage)
  • 47. int const Uninitialized = 0; int const BeingInitialized = -1; int const EpochStart = INT_MIN; // Access to these variables is guarded in the below functions. They may only // be modified while the lock is held. _Tss_epoch is readable from user // code and is read without taking the lock. extern "C" { int _Init_global_epoch = EpochStart; __declspec(thread) int _Init_thread_epoch = EpochStart; } static CRITICAL_SECTION _Tss_mutex; static CONDITION_VARIABLE _Tss_cv; static HANDLE _Tss_event; static decltype(SleepConditionVariableCS)* encoded_sleep_condition_variable_cs; static decltype(WakeAllConditionVariable)* encoded_wake_all_condition_variable; Magic Statics
  • 48. Magic Statics • 앞의 Single 클래스 예제를 다시 가져와 보자 class Single { private: Single() { std::cout << "Constructorn"; } public: ~Single() { std::cout << "Destructorn"; } static Single& Instance() { static Single s; return s; } };
  • 49. Magic Statics • Visual Studio 2015는 다음과 같은 형태로 코드를 만든다 int g_single_once = Uninitialized; static Single& Single::Instance() { if (g_single_once > _Init_thread_epoch) { _Init_thread_header(&g_single_once); if (g_single_once == BeingInitialized) { Single::Single(); atexit(Single::~Single); _Init_thread_footer(&g_single_once); } } }
  • 50. Magic Statics • Visual Studio 2015는 다음과 같은 형태로 코드를 만든다 int g_single_once = Uninitialized; static Single& Single::Instance() { if (g_single_once > _Init_thread_epoch) { _Init_thread_header(&g_single_once); if (g_single_once == BeingInitialized) { Single::Single(); atexit(Single::~Single); _Init_thread_footer(&g_single_once); } } } g_single_one는 0으로 초기화 _Init_thread_epoch는 0x80000000으로 초기화
  • 51. Magic Statics • 문제는 _Init_thread_epoch가 TLS 변수라는 점! • Visual Studio 2015에서는 이를 위해 _declspec(thread)를 사용해 암시적 TLS로 처리하는데, Windows XP에서는 암시적 TLS를 정상적으로 지원하지 않아 _Init_thread_epoch가 0으로 초기화됐고, 그러면서 생성도 되지 않은 개체가 생성됐다고 판단이 이루어진 것
  • 52. Magic Statics extern "C" void __cdecl _Init_thread_header(int* const pOnce) { _Init_thread_lock(); if (*pOnce == Uninitialized) { *pOnce = BeingInitialized; } else { while (*pOnce == BeingInitialized) { _Init_thread_wait(XpTimeout); if (*pOnce == Uninitialized) { *pOnce = BeingInitialized; _Init_thread_unlock(); return; } } _Init_thread_epoch = _Init_global_epoch; } _Init_thread_unlock(); }
  • 53. Magic Statics extern "C" void __cdecl _Init_thread_footer(int* const pOnce) { _Init_thread_lock(); ++_Init_global_epoch; *pOnce = _Init_global_epoch; _Init_thread_epoch = _Init_global_epoch; _Init_thread_unlock(); _Init_thread_notify(); }
  • 54. Magic Statics • 결론 : Visual Studio 2015에서 프로젝트가 Windows XP를 지원하도록 설정한 경우, Windows XP에서 암시적 TLS를 정상적으로 지원하지 않기 때문에 생기는 문제 • Visual Studio 2015에서는 “Thread-safe Initialization” 옵션이 기본적으로 활성화되어 있음
  • 55. Magic Statics • 해결 : 프로젝트 속성에서 C/C++ > Command Line에 “/Zc:threadSafeInit-”를 추가 (비활성화)
  • 56. Treat Warnings as Errors • Visual Studio 2015로 오면서 경고를 오류로 취급하는 문제 • C4456 : declaration of ‘x’ hides previous local declaration. • C4459 : declaration of 'x' hides global declaration. • C4577 : 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc • C4819 : The file contains a character that cannot be represented in the current code page (949). Save the file in Unicode format to prevent data loss.
  • 57. Treat Warnings as Errors • 해결 방법 : C/C++ > Advanced의 “Disable Specific Warnings” 에 무시할 경고 번호를 추가하면 됨
  • 59. Before Merge: Test, test, test it! • 마이그레이션 작업을 마친 후 프로젝트가 빌드되는지 확인 • 빌드되면 끝? 이제 시작일 뿐! • 코드 변경으로 인해 기능이 동작하지 않는 경우가 발생할 수 있음 • 또한 코드 변경으로 인해 예상하지 못한 런타임 오류가 발생할 수 있음 • 오랜 시간이 걸리더라도 수행 가능한 범위 내에서 모든 기능을 테스트 • 무엇보다 중요한 것은 라이브 서비스의 안전성!
  • 61. After Merge: Test, test, test it again! • 변경한 코드를 머지한 뒤, 다시 한 번 테스트를 수행 • 기존 프로젝트에서 빌드되고 문제없이 실행되어야 함 또한 마이그레이션한 프로젝트에서도 마찬가지여야 함 • 라이브 서비스로 내보내기 전, 반드시 거쳐야 할 작업! 최대한 많은 인원이 테스트를 할 수 있도록 일정 협의
  • 62. Visual Studio 2015의 유용한 기능 - Code Analysis
  • 63. Code Analysis • Visual Studio 2013, 2015에는 정적 분석 도구가 내장되어 있음 • Analyze > Run Code Analysis 메뉴에서 사용 가능 • 각 프로젝트 속성에서 정적 분석에 사용할 규칙 집합 설정 • Platform Toolset이 “Visual Studio 2015 – Windows XP”인 경우 정적 분석을 할 수 없기 때문에 “Visual Studio 2015”로 변경 • 정적 분석 시간은 프로젝트의 크기에 따라 달라짐
  • 64. Code Analysis • 정적 분석을 통해 확인할 수 있는 부분 • NULL 포인터 역참조 • int -> bool 변환 • noexcept 누락 • 부호 불일치 • 지역 변수 / 함수 매개 변수 / 클래스 선언 숨김 • …
  • 65. Code Analysis • Demo : 프로젝트의 코드 정적 분석
  • 68. Summary • 마이그레이션 작업 전에 정책 및 계획을 잘 세우시기 바랍니다. • 마이그레이션 작업은 매우 힘든 작업입니다. 그렇다고 아예 불가능한 작업도 아닙니다. • 마이그레이션 작업 후에는 최대한 모든 기능을 테스트합시다. • 뜻이 있는 곳에 길이 있습니다. • 모든 개발자 분들, 언제나 파이팅입니다!
  • 69. Special Thanks to • 마이그레이션 작업은 저 혼자가 아닌 팀에 계신 분들과 함께 진행했습니다. 함께 작업했기에 무사히 마칠 수 있었습니다. 이 자리를 빌어 저희 팀원분들에게 감사하다는 말씀드립니다.
  • 70. References • http://www.cppreference.com/ • http://eslife.tistory.com/entry/Visual-Studio- %EB%B2%84%EC%A0%84-%EB%B3%84-STL- %EC%A7%80%EC%9B%90 • http://jiniya.net/ng/2016/11/magic-statics/ • https://blogs.msdn.microsoft.com/vcblog/2014/11/12/improve ments-to-warnings-in-the-c-compiler/