[C++ Korea 2nd Seminar] C++17 Key Features SummaryChris Ohk
C++은 10년 만에 C++11/14를 발표하면서 '모던 C++'이라는 이름으로 발전했습니다. 그만큼 새로운 기능들이 많이 추가되었습니다. 그리고 2017년, C++은 C++17이라는 이름으로 또 한 번의 발전을 준비하고 있습니다. 3년 주기로 빠르게 변화하는 모던 C++에 대비하기 위해, C++17에 추가될 주요 기능들을 살펴보고자 합니다.
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기Chris Ohk
C++11을 시작으로 모던 C++이 도입된 지도 어느새 6년이라는 시간이 흘렀습니다. 올해는 C++17 표준이 도입될 예정입니다. 그만큼 많이 개선되고 새로운 기능들이 많이 도입되었기에 실무에서 사용해보고 싶은 경우도 많습니다. 하지만 이미 서비스 중이라 기존 프로젝트를 새 버전의 VS로 마이그레이션하기 어려운 프로젝트가 많습니다. 그렇다고 아예 불가능한 일도 아닙니다. 이번 세미나에서는 기존 프로젝트를 새 버전의 VS로 마이그레이션하면서 발생했던 문제와 마이그레이션 이후 모던 C++을 사용하면서 발생했던 문제, 그리고 해결법을 설명하고자 합니다. 또한 새 버전의 VS에 생긴 유용한 기능들도 함께 알려드립니다.
[C++ Korea 2nd Seminar] C++17 Key Features SummaryChris Ohk
C++은 10년 만에 C++11/14를 발표하면서 '모던 C++'이라는 이름으로 발전했습니다. 그만큼 새로운 기능들이 많이 추가되었습니다. 그리고 2017년, C++은 C++17이라는 이름으로 또 한 번의 발전을 준비하고 있습니다. 3년 주기로 빠르게 변화하는 모던 C++에 대비하기 위해, C++17에 추가될 주요 기능들을 살펴보고자 합니다.
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기Chris Ohk
C++11을 시작으로 모던 C++이 도입된 지도 어느새 6년이라는 시간이 흘렀습니다. 올해는 C++17 표준이 도입될 예정입니다. 그만큼 많이 개선되고 새로운 기능들이 많이 도입되었기에 실무에서 사용해보고 싶은 경우도 많습니다. 하지만 이미 서비스 중이라 기존 프로젝트를 새 버전의 VS로 마이그레이션하기 어려운 프로젝트가 많습니다. 그렇다고 아예 불가능한 일도 아닙니다. 이번 세미나에서는 기존 프로젝트를 새 버전의 VS로 마이그레이션하면서 발생했던 문제와 마이그레이션 이후 모던 C++을 사용하면서 발생했던 문제, 그리고 해결법을 설명하고자 합니다. 또한 새 버전의 VS에 생긴 유용한 기능들도 함께 알려드립니다.
C++은 10년 만에 C++11/14를 발표하면서 '모던 C++'이라는 이름으로 발전했습니다. 그만큼 새로운 기능들이 많이 추가되었습니다. 그리고 2017년, C++은 C++17이라는 이름으로 또 한 번의 발전을 준비하고 있습니다. 3년 주기로 빠르게 변화하는 모던 C++에 대비하기 위해, C++17에 추가될 주요 기능들을 살펴보고자 합니다.
이 발표는 이전에 발표했던 내용에서 일부 사례 추가 및 최신 내용으로 갱신한 버전입니다.
http://github.com/ipkn/crow
Crow 프로젝트에서 사용한 C++11 기법들을 실제 구현에 대한 설명을 포함하여 자세히 설명한 발표자료입니다.
C++11 features used in Crow
video:
http://youtu.be/MixS9c3mE6U
https://vimeo.com/119627253
boost라이브러리 중에서 가장 많이 사용하는 기능인 BOOST_FOREACH()와 shared_ptr의 내부 구조를 분석합니다. 그리고 boost의 내부 구현에 사용된 이 기능을 프로그래밍에 응용하는 방법을 제시합니다.
* BOOST_FOREACH 구조 분석 및 응용
* shared_ptr 구조 분석 및 응용
모던 C++의 시초인 C++11은 C++ 코드 전반에 많은 변화를 가져왔습니다. 그리고 최근 C++20의 표준위원회 회의가 마무리되었습니다. 내년에 C++20이 도입되면 C++11이 처음 도입되었을 때와 비슷한 규모, 또는 그 이상의 변화가 있을 것이라고 예상하고 있습니다. C++20에는 Concepts, Contract, Ranges, Coroutine, Module 등 굵직한 기능 외에도 많은 기능들이 추가될 예정입니다. 이번 세션에서는 C++20에 추가될 주요 기능들을 살펴보고자 합니다.
C++은 10년 만에 C++11/14를 발표하면서 '모던 C++'이라는 이름으로 발전했습니다. 그만큼 새로운 기능들이 많이 추가되었습니다. 그리고 2017년, C++은 C++17이라는 이름으로 또 한 번의 발전을 준비하고 있습니다. 3년 주기로 빠르게 변화하는 모던 C++에 대비하기 위해, C++17에 추가될 주요 기능들을 살펴보고자 합니다.
이 발표는 이전에 발표했던 내용에서 일부 사례 추가 및 최신 내용으로 갱신한 버전입니다.
http://github.com/ipkn/crow
Crow 프로젝트에서 사용한 C++11 기법들을 실제 구현에 대한 설명을 포함하여 자세히 설명한 발표자료입니다.
C++11 features used in Crow
video:
http://youtu.be/MixS9c3mE6U
https://vimeo.com/119627253
boost라이브러리 중에서 가장 많이 사용하는 기능인 BOOST_FOREACH()와 shared_ptr의 내부 구조를 분석합니다. 그리고 boost의 내부 구현에 사용된 이 기능을 프로그래밍에 응용하는 방법을 제시합니다.
* BOOST_FOREACH 구조 분석 및 응용
* shared_ptr 구조 분석 및 응용
모던 C++의 시초인 C++11은 C++ 코드 전반에 많은 변화를 가져왔습니다. 그리고 최근 C++20의 표준위원회 회의가 마무리되었습니다. 내년에 C++20이 도입되면 C++11이 처음 도입되었을 때와 비슷한 규모, 또는 그 이상의 변화가 있을 것이라고 예상하고 있습니다. C++20에는 Concepts, Contract, Ranges, Coroutine, Module 등 굵직한 기능 외에도 많은 기능들이 추가될 예정입니다. 이번 세션에서는 C++20에 추가될 주요 기능들을 살펴보고자 합니다.
Let's make APM by instrumenting Nodejs through the knowledge gained through tracing. Creating clues that facilitate tracking becomes a milestone for latecomers, like a snow-footprint.
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계Sungkyun Kim
이미 많은 개발자들이 C#의 장점을 누리고 있으나, 본 PT에서는 높은 성능과 생산성을 동시에 달성하기 위해 C/C++로 개발된 native 게임 코드에 스크립트 언어로서 C#을 통합 할 수 있는 방법을 제시한다. 이를 위해 오픈소스 .Net 프레임웍인 Mono의 사용방법과 모바일 플랫폼에서의 특이사항들을 자세히 설명한다.
또한, C/C++언어에 C#을 비롯한 다양한 스크립트 언어를 효율적으로 혼합하여 게임을 구현할 수 있는 아키텍처를 제시한다. clang과 reflection을 이용하여 서로 다른 언어 간 인터페이스 노출을 자동화하고, 게임 내 오브젝트의 생명주기를 자동으로 관리할 수 있는 기법에 대해 설명한다.
[C++ Korea] Effective Modern C++ Study item14 16 +신촌Seok-joon Yun
[C++ Korea] Effective Modern C++ Study item14 16 +신촌
Item 14 : Declare functions noexcept if they won't emit exceptions. +윤석준
Item 15 : Use constexpr whenever possible. +이동우
Item 16 : Make const member functions thread safe. +제한재
17. 케이스 바이 케이스
• 타입에 따른 조건부 컴파일은 함수 템플릿을 통해 개선한다.
• 하지만 #ifdef를 사용해야 되는 경우도 있다.
• 32비트 vs 64비트 코드
• DEBUG 모드 vs Non-DEBUG 모드
• 컴파일러, 플랫폼, 언어에 따라 다른 코드
• 반드시 사용해야 된다면, 코드를 단순화하는 것이 좋다.
• 중첩 #ifdef를 피하고, 함수의 일부를 조건부 컴파일에 넣지 않도록 한다.
18. 매크로
• #define …
• 변수 대신 사용하는 매크로 : #define RED 1
• 함수 대신 사용하는 매크로 : #define SQUARE(x) ((x) * (x))
• 수많은 문제를 일으키는 장본인
• 컴파일러가 타입에 대한 정보를 갖기 전에 계산됨
• 필요 이상으로 많이 사용
20. #define red 0
#define orange 1
#define yellow 2
#define green 3
#define blue 4
#define purple 5
#define hot_pink 6
void f()
{
unsigned orange = 0xff9900;
}
warning C4091: '' : ignored on left of 'unsigned int' when no variable is declared
error C2143: syntax error : missing ';' before 'constant'
error C2106: '=' : left operand must be l-value
21. #define red 0
#define orange 1
#define yellow 2
#define green 3
#define blue 4
#define purple 5
#define hot_pink 6
void f()
{
unsigned 2 = 0xff00ff;
}
warning C4091: '' : ignored on left of 'unsigned int' when no variable is declared
error C2143: syntax error : missing ';' before 'constant'
error C2106: '=' : left operand must be l-value
22. #define RED 0
#define ORANGE 1
#define YELLOW 2
#define GREEN 3
#define BLUE 4
#define PURPLE 5
#define HOT_PINK 6
void g(int color); // valid values are 0 through 6
void f()
{
g(HOT_PINK); // Ok
g(9000); // Not ok, but compiler can’t tell
}
23. enum color_type
{
red = 0,
orange = 1,
yellow = 2,
green = 3,
blue = 4,
purple = 5,
hot_pink = 6
};
24. enum color_type
{
red, orange, yellow, green, blue, purple, hot_pink
};
void g(color_type color);
void f()
{
g(hot_pink); // Ok
g(9000); // Not ok, compiler will report error
}
error C2664: 'void g(color_type)' : cannot convert argument 1 from 'int' to 'color_type'
25. enum color_type
{
red, orange, yellow, green, blue, purple, hot_pink
};
void f()
{
int x = red; // Ugh
int x = red + orange; // Double ugh
}
35. // Old, ugly macro implementation:
#define make_char_lowercase(c)
((c) = (((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
// New, better function implementation:
inline char make_char_lowercase(char& c)
{
if (c > 'A' && c < 'Z')
{
c = c - 'A' + 'a';
}
return c;
}
36. 열거체, 함수를 사용하자
• 변수 대신 사용하는 매크로에는 열거체를 사용하자.
• 열거체에서 발생할 수 있는 문제는 enum class로 해결할 수 있다.
• 열거체 대신 ‘static const’ 변수를 사용하는 방법도 있다.
• 함수 대신 사용하는 매크로에는 함수를 사용하자.
• 읽기 쉽고, 유지보수하기 쉽고, 디버깅하기 쉽다.
• 성능에 따른 오버헤드도 없다.
41. void ExampleWithoutRAII() {
std::FILE* file_handle = std::fopen("logfile.txt", "w+");
if (file_handle == nullptr)
throw std::runtime_error("File couldn't open!");
try {
if (std::fputs("Hello, Log File!", file_handle) == EOF)
throw std::runtime_error("File couldn't write!");
// continue writing to logfile.txt ... do not return
// prematurely, as cleanup happens at the end of this function
}
catch (...)
{
std::fclose(file_handle);
throw;
}
std::fclose(file_handle);
}
42. RAII
• 자원 획득은 초기화다 (Resource Acquisition Is Initialization)
• 객체의 생성에 맞춰 메모리와 시스템 리소스를 자동으로 할당
• 객체의 소멸에 맞춰 메모리와 시스템 리소스를 자동으로 해제
→ 생성자 안에서 리소스를 할당하고, 소멸자에서 리소스를 해제
45. 다시 발생하는 문제
• 파일 입출력과 관련한 예외 처리를 간편하게 하기 위해
File 클래스를 만들어 생성자와 소멸자로 처리했다.
• 하지만, 정작 File 클래스를 동적으로 할당하는 경우
소멸자가 호출되지 않아 파일을 닫지 않는 문제가 발생한다.
• 좋은 방법이 없을까?
→ 스마트 포인터(Smart Pointer)의 등장!
46. 스마트 포인터
• 좀 더 똑똑한 포인터
• 스마트 포인터를 사용하면 명시적으로 해제할 필요가 없다.
• 사용하는 이유
• 적은 버그, 자동 청소, 자동 초기화
• Dangling 포인터 발생 X, Exception 안전
• 효율성
48. 스마트 포인터의 종류
• 경우에 따라 여러 종류의 스마트 포인터를 사용할 수 있다.
• shared_ptr : 객체의 소유권을 복사할 수 있는 포인터
(여러 shared_ptr 객체가 같은 포인터 객체를 가리킬 수 있음)
• unique_ptr : 객체의 소유권을 복사할 수 없는 포인터
(하나의 unique_ptr 객체만이 하나의 포인터 객체를 가리킬 수 있음)
49. std::unique_ptr
ptrA Song 개체
ptrA Song 개체
ptrB
auto ptrA = std::make_unique<Song>(L"Diana Krall", L"The Look of Love");
auto ptrB = std::move(ptrA);
50. std::unique_ptr<Song> SongFactory(const std::wstring& artist, const std::wstring& title)
{
// Implicit move operation into the variable that stores the result.
return std::make_unique<Song>(artist, title);
}
void MakeSongs()
{
// Create a new unique_ptr with a new object.
auto song = std::make_unique<Song>(L"Mr. Children", L"Namonaki Uta");
// Use the unique_ptr.
std::vector<std::wstring> titles = { song->title };
// Move raw pointer from one unique_ptr to another.
std::unique_ptr<Song> song2 = std::move(song);
// Obtain unique_ptr from function that returns by value.
auto song3 = SongFactory(L"Michael Jackson", L"Beat It");
}
53. // Use make_shared function when possible.
auto sp1 = std::make_shared<Song>(L"The Beatles", L"Im Happy Just to Dance With You");
// Ok, but slightly less efficient.
// Note: Using new expression as constructor argument
// creates no named variable for other code to access.
std::shared_ptr<Song> sp2(new Song(L"Lady Gaga", L"Just Dance"));
// When initialization must be separate from declaration, e.g. class members,
// initialize with nullptr to make your programming intent explicit.
std::shared_ptr<Song> sp5(nullptr);
//Equivalent to: shared_ptr<Song> sp5;
//...
sp5 = std::make_shared<Song>(L"Elton John", L"I'm Still Standing");
54. 리소스 관리는 스마트 포인터로
• RAII를 사용하자!
• 읽고, 쓰고, 유지보수하기 쉽다.
• 자원 관리에 대한 걱정을 할 필요가 없다.
• C++ 코드 품질을 향상시키는 가장 쉬운 방법!
• 기왕이면 스마트 포인터로!
• shared_ptr
• unique_ptr
64. HANDLE hT = CreateThread(NULL, 0, [](LPVOID lpThreadParameter) -> DWORD {
for (int i = 0; i < 1000; i++) {
this_thread::sleep_for(milliseconds{ 10 });
cout << i << endl;
}
return 0;
}, NULL, 0, NULL);
65. 람다식을 사용하자
• 짧고, 간결하고, while 문과 같은 행사 코드 없이
깔끔하게 작성할 수 있다.
• 수십줄의 코드를 1~2줄로 간추릴 수 있다.
• Functor, Callback Function을 대체해서 사용할 수 있다.
• 반복적으로 사용하는 함수가 아니라면 람다식을 사용하자!
67. auto 키워드
• 컴파일 타임에 타입을 추론해 어떤 타입인지 결정한다.
• 컴파일 타임에 추론이 불가능하다면, 오류가 발생한다.
std::vector<std::tuple<std::string, int, double>> vStudents;
for (std::vector<std::tuple<std::string, int, double>>::iterator iter =
vStudents.begin(); iter != vStudents.end(); ++iter) { … }
std::vector<std::tuple<std::string, int, double>> vStudents;
for (auto iter = vStudents.begin(); iter != vStudents.end(); ++iter) { … }
68. 범위 기반 for문
int arr[] = { 1, 2, 3, 4, 5 };
for (int i = 0; i < 5; ++i)
std::cout << arr[i] << std::endl;
return 0;
}
int arr[] = { 1, 2, 3, 4, 5 };
for (auto& i : arr)
std::cout << i << std::endl;
return 0;
}
69. 정리
// circle and shape are user-defined types
circle* p = new circle(42);
vector<shape*> v = load_shapes();
for (vector<circle*>::iterator i = v.begin(); i != v.end(); ++i) {
if (*i && **i == *p)
cout << **i << " is a matchn";
}
for (vector<circle*>::iterator i = v.begin(); i != v.end(); ++i) {
delete *i; // not exception safe
}
delete p;
70. 정리
// circle and shape are user-defined types
auto p = make_shared<circle>(42);
vector<shared_ptr<shape>> v = load_shapes();
for_each(begin(v), end(v), [&](const shared_ptr<shape>& s) {
if (s && *s == *p)
cout << *s << " is a matchn";
});
71. 정리
• 대체할 수 있는 조건부 컴파일은 템플릿으로 기름칠!
• 매크로는 가급적 사용하지 말고 열거체와 함수로 기름칠!
• 리소스 관리에는 RAII, 기왕이면 스마트 포인터로 기름칠!
• 일회성으로 사용하는 함수는 람다식으로 기름칠!
• 복잡한 타입에는 auto로 기름칠!
• 반복 횟수에 고통받지 말고 범위 기반 for문으로 기름칠!
72. 정리
• 모던 C++을 통해 대체할 수 있는 코드는 많습니다!
(하지만 제한된 시간으로 인해 …)
• 다음 사이트에서 모던 C++ 예제 코드를 확인하실 수 있습니다.
http://www.github.com/utilForever/ModernCpp
• C++ 핵심 가이드라인
• 영문 : https://github.com/isocpp/CppCoreGuidelines
• 한글 : https://github.com/CppKorea/CppCoreGuidelines