-
GCC 확장 기능 2
서론 지난 글에서는 GCC에서 다양한 목적들을 가진 방대한 양의 확장 기능들을 제공한다는 것을 보았습니다. 이번 글에서는 지난 글에 이어 더 많은 확장 기능들을 살펴보고 어떻게 활용할 수 있을지에 대해 설명하도록 하겠습니다. 포인터를 사용한 goto 표준에서 goto문은 이름을 지정한 레이블로만 점프가 가능합니다. GCC에서는 이를 확장시켜서, 레이블이 위치한 주소를 얻어와 포인터를 사용하여 goto를 할 수 있도록 만들어 줍니다. 예시 코드는 다음과 같습니다. #include <stdio.h> int main(void) { int i = 0; void *ptr = &&start; start: printf("hello\n");...
-
Effective Modern C++ (3)
저번시간에 이어서 오늘은 예전에 Effective Modern C++ 을 공부하며 정리했던 내용들을 포스팅해볼까 합니다~ C++11/14 에서의 best practice 에 관한 내용으로서 최근 C++20 이 나오는 시점에서 이 또한 최신 내용은 아니긴 하지만 여전히 많은 부분들이 유효합니다. Chapter 6. 람다 표현식 항목 31. 기본 갈무리 모드를 피하라. 참고로, 갈무리는 ‘capture’를 의미한다. (첨엔 어색했으나 나도 이제 완전히 이 번역에 익숙해져버렸다.) 기본 갈무리 모드 (default capture mode)는 ‘참조 갈무리 모드’와 ‘값 갈무리 모드’가 있다. 기본 갈무리 모드를 피해야 하는...
-
C/C++의 undefined behavior
C나 C++에 있어서 가장 곤혹스러운 요소 중 하나인 undefined behavior는 입문자부터 숙련자에 이르기까지 까다로운 디버깅을 요합니다. 흔히 나오는 코딩 실수인 배열 인덱스 오류도 undefined behavior이며, 온라인 저지 등에서는 최적화 옵션이 켜지면서 전혀 다른 효과가 일어날 수 있습니다. 꼭 C++에만 국한된 이야기는 아니지만, C++ undefined behavior의 주된 요인 중 하나인 signed integer overflow는 2019년에만 1247개의 CVE 취약점을 낳았습니다. 그렇다고 모든 사람이 C/C++ 스펙을 머릿속에 넣어야 하는 것도 아닐 뿐더러 그럴 수도 없습니다. 이 포스트에서는 undefined behavior의...
-
GCC 확장 기능
서론 프로그래밍을 하면서 C나 C++의 레퍼런스를 찾다 보면 표준의 디테일에 놀라게 되는 경우가 많습니다. 평소에는 무심하게 사용해왔던 문법에 들어있는 다양한 제약 조건이나, 키워드들의 알지 못했던 쓰임새들을 종종 보게 됩니다. 그런데 그렇게 방대한 스펙을 가지고도 사람들은 더 많은 것을 바라기 마련입니다. 표준상으로는 지원되지 않는 문법을 통해 더욱 편리한 코드를 만들거나, 어셈블리 명령을 직접 적어넣지 않아도 프로세서의 좋은 기능을 컴파일러가 최대한 살릴 수 있게 보장해 주었으면 하는 등 끝없이 더 많은 기능을 원하고 있습니다. 이를 충족시키기 위해...
-
Effective Modern C++ (2)
저번시간에 이어서 오늘은 예전에 Effective Modern C++ 을 공부하며 정리했던 내용들을 포스팅해볼까 합니다~ C++11/14 에서의 best practice 에 관한 내용으로서 최근 C++20 이 나오는 시점에서 이 또한 최신 내용은 아니긴 하지만 여전히 많은 부분들이 유효합니다. Chapter 4. 똑똑한 포인터 (Smart Pointer) 항목 18. 소유권 독점 자원의 관리에는 std::unique_ptr를 사용하라. 보통 smart pointer를 처음 접한 사람들은 std::shared_ptr만을 남용(?)하는 경향이 있다.그러나 std::shared_ptr이 매우 강력한 존재이긴 하지만 크게 2가지 측면에서 단점이 있다. 첫 번째는 overhead이다. 참조 계수를 관리하기...
-
C++ STL 컨테이너의 메모리 사용량 (2)
지난 포스트 C++ STL 컨테이너의 메모리 사용량 (1)에서는 list, vector, deque의 내부 메모리 사용량을 분석하고, 어떤 식으로 구현되어있는지 추측해보았습니다. 이번 시간에는 priority_queue, set, map, unordered_map을 다루도록 하겠습니다. priority_queue 컨테이너 priority_queue 컨테이너는 다음과 같은 형태로 정의됩니다. template< class T, class Container = std::vector<T>, class Compare = std::less<typename Container::value_type> > class priority_queue; T는 타입, Container는 내부적으로 사용할 컨테이너, Compare는 heap을 구축하는데 사용할 함수를 의미합니다. 기본적으로 priority_queue는 std::vector<T>를 이용하고, std::less를 통해 max heap을 만듭니다. priority_queue는 heapify 등을 통해서...
-
Effective Modern C++
오늘은 예전에 Effective Modern C++ 을 공부하며 정리했던 내용들을 포스팅해볼까 한다. C++11/14 에서의 best practice 에 관한 내용으로서 최근 C++20 이 나오는 시점에서 이 또한 최신 내용은 아니긴 하지만 여전히 많은 부분들이 유효한 내용들이라서 큰 도움이 된다고 생각한다. Chapter 1. 형식 연역 (Type Deduction) 항목 1. 템플릿 형식 연역 규칙을 숙지하라. 아래에 적어놓은 코드를 보면 C++11/14에서의 Template Type Deduction 규칙을 파악할 수 있을 것이다. 대부분 직관과 거의 잘 맞아떨어진다. 그래도 주의 할 점 몇가지를 살펴보면,...
-
C++ STL 컨테이너의 메모리 사용량 (1)
C++로 Problem Solving을 하는 사람도, 일반적인 프로그래밍을 하는 사람도 C++의 컨테이너는 매우 유용하게 사용합니다. 대표적인 예시가 동적 배열인 vector, 이진 탐색 트리인 set 등입니다. 이러한 자료구조를 적재적소에 사용하지 않으면 시간/공간 복잡도가 예상을 뛰어넘을 수 있습니다. 대표적인 예시가 “priority_queue가 set보다 빠르다”는 말입니다. 이는 일반적으로 사실이지만, 왜 그럴까요? 이와 관련된 질문에 답하기 위해 C++ 컨테이너가 메모리를 원소별로 얼마나 할당하고 그 이유는 무엇일지 gmem이라는 라이브러리를 통해 파트별로 알아보도록 하겠습니다. gmem 라이브러리 gmem은 동적으로 메모리를 할당할 때마다 로그를 남기고,...
-
Google Test와 gcov 소개
이 글에서는 Google Test를 이용하여 간단한 c++ 유닛 테스트 코드를 작성해보고 이후 gcov를 이용하여 코드 커버리지를 측정하는 방법에 대해서 다뤄보겠습니다. 유닛 테스트란? 유닛 테스트는 특정 모듈(함수 or 특정 코드)이 내가 원하는 바 대로 정확히 작동하는지 검증하는 절차입니다. 즉, 모든 함수와 메소드에 대한 테스트 케이스를 작성하는 절차를 말합니다. 우리는 이를 자동화하고 반복할 수 있게 하여 코드가 수정되어 문제가 발생하였을 경우에 이를 빠르게 찾고 수정할 수 있도록 해주고, 유닛 테스트를 통과했다면 해당 모듈이 잘 작동하고 있음을 확신하고...
-
SHA-256 구현
안녕하세요. 오늘은 SHA-256 알고리즘에 대해 간단하게 설명하려고 합니다~ 이 포스팅에서는 SHA-256 의 수학적인 원리나 구현 최적화 기법에 대해서는 다루지 않습니다. 설명을 위해 최소한으로 작성한 C++ 코드를 통해 SHA-256 의 내부 로직이 어떻게 구성되어 있는지 가볍게 알아보도록 하겠습니다. » 이 글을 좀 더 좋은 가독성으로 읽기 « SHA-256 이란? 해시 함수중에 하나로서, 해시의 결과가 256bit 입니다. SHA 해시 함수 모음에 속하고 대중적으로 널리쓰이는 해시 함수중에 하나입니다. 특히 최근에는 비트코인을 비롯한 많은 블록체인 시스템에서 SHA-256 을 주로...
-
Boost.Exception 소개
안녕하세요~ 오늘은 Boost.Exception 에 대해서 간단하게 소개해볼까 합니다. » 이 글을 좀 더 좋은 가독성으로 읽기 « Boost.Exception 이란? Boost.Exception 은 예외 계층을 설계하고 예외 핸들링을 수행할 때 도움을 주는 라이브러리입니다. 제가 Boost.Exception 을 사용하면서 얻을 수 있었던 이점은 다음과 같습니다. 예외가 발생한 시점의 소스파일 이름, 라인 넘버, 함수명을 예외 객체에 쉽고 편하게 담을 수 있습니다. throw std::exception() 대신에 BOOST_THROW_EXCEPTION(std::exception()) 을 사용하면 std::exception 을 wrapping 하는 예외 객체가 만들어지고 그 안에 소스파일 이름, 라인 넘버,...
-
HPX parallel partition 알고리즘
안녕하세요. 오늘은 제가 예전에 HPX 라는 오픈소스에 구현했던 parallel partition 알고리즘에 대해 간단히 소개하고 설명하는 시간을 가져보도록 하겠습니다. » 이 글을 좀 더 좋은 가독성으로 읽기 « 출처 먼저 이 포스팅에서 다루는 알고리즘/코드의 출처는 다음과 같습니다. HPX : https://github.com/STEllAR-GROUP/hpx 관련 MR : https://github.com/STEllAR-GROUP/hpx/pull/2778 소스코드 : https://github.com/STEllAR-GROUP/hpx/blob/master/hpx/parallel/algorithms/partition.hpp 소개 parallel partition 알고리즘은 여러 개의 연산 유닛 (쉽게 말하면 cpu) 들을 이용해서 partition 알고리즘을 수행하는 것을 말합니다. 이 포스팅에서는 독자가 partition 알고리즘에 대해서 이미 알고있다고 가정합니다. partition 알고리즘에...
-
C++ Boost 라이브러리를 Windows XP 에서 동작하도록 빌드하기
안녕하세요~ 반갑습니다! C++ 개발자 여러분~ boost 많이 쓰시죠?? 저도 boost 참 좋아합니다 ㅎㅎ 이렇게 좋은 boost 를 Windows XP/2003 환경에서 사용할 때는 그냥 일반적인 방법으로는 사용이 불가능한데요. 그래서 오늘은 Windows XP 환경에서 동작하도록 boost 를 빌드하는 방법에 대해서 알아보도록 하겠습니다! » 이 글을 좀 더 좋은 가독성으로 읽기 « 참고로 제가 설명할 방법은 100% 완벽하게 검증된 방법은 아니며, 제가 조사/연구를 통해 알아낸 방법입니다. 따라서 문제가 있을 수도 있으므로 참고자료정도로만 사용해주시면 감사하겠습니다. 그리고 이 포스팅에서는 Visual...