[CMake, CGold] 2. First Step
Native build toolCMake는 빌드를 스스로 하려고 디자인된 도구가 아니다. 이는 실제 native build tool 파일을 생성한다. 그러므로 CMake를 사용할 때는 도구를 선택하고 필요하다면 설치해야 한다. 옵션 `-G `은 사용할 제너레이터의 타입을 지정할 때 사용된다. 만약 옵션이 없다면, CMake는 디폴트 제너레이터를 사용할 것이다. (예를 들어, nix 플랫폼이라면 `Unix Makefiles`) 사용 가능한 제너레이터 목록은 호스트 운영체제에 따라 달라진다(예: Visual Studio 계열 제너레이터는 Linux에서는 사용할 수 없다). 이 목록른 `cmake --help`명령을 통해 얻을 수 있다. > cmake --help...GeneratorsThe following..
2026.01.24
no image
[CMake, CGold] 1.Overview - What can’t be done with CMake
CMake로 할 수 없는 것들CMake도 장점과 단점이 존재한다. 그래도 여기서 언급되는 대부분의 단점들은 평소 워크플로우와는 조금 다른 방식으로 접근하면 우회해서 해결할 수 있다. 전체 그림을 놓고 생각해보면 CMake 장점이 단점보다 훨씬 더 크다. CMake의 언어 및 문법 관점CMake 언어는 다른 어떤 언어와도 쉽게 비교할 수 있는 종류의 언어는 아니다. 클래스, 맵, 가상 함수, 람다는 존재하지 않는다. 심지어 함수의 입력 매개변수들을 파싱하는 것이나 함수로부터 값을 반환하는 기본 작업 또한 쉽지 않다. 일반 프로그래밍 언어처럼 알고리즘 구현이나 JSON 응답 처리같은 기능을 구현할만한 언어는 절대 아니다. 하지만 일반적인 개발 작업을 다루는 데에는 아주 효율적이다. 만약, 비표준적인 행위를 ..
2026.01.21
no image
[CMake, CGold] 1. Overview - What CMake can do
OverviewCMake는 meta build sytstem이다. 이는 추상화된 텍스트 구성(configuration))으로부터 실제로 native build tool 파일을 생성한다. 대개 이 코드들은 `CMakeLists.txt` 파일에 있다. 서로 다른 플랫폼/IDE에서 공유디는 C++ 프로젝트가 포함된 크로스 플랫폼 프로젝트가 있다고 가정해보자. Windows에서는 Visual studio, OSX에서는 Xcode, Linux에서는 Makefile을 사용한다고 하면 `bar.cpp`를 추가하기 위해 각각 다른 tool에 일일히 파일을 새로 추가해야 한다. 특히 빨간색 화살표는 수동으로 해야하는 작업을 의미한다. 일관된 환경을 유지하기 위해 비슷한 업데이트를 여러 번 반복해야하며, 이를 수동으로 수..
2026.01.21
[OpenGL] glPointSize()의 값 지정
문제 상황pointSize_를 어떻게 지정하던간에, 시각화되는 포인트의 크기가 1.0~1.4이라도 시각적으로 동일하게 보이고, 1.5~2.4도 동일해 보인다. 셰이더 안에서 point 크기를 다루어도 동일한 현상이 발생한다. glPointSize(pointSize_);glDrawArrays(GL_POINTS, 0, points.size()); 공식 설명glPointSize함수는 점의 래스터화 된 지름을 정한다고 한다. point size 모드가 비활성화된 경우 (`GL_PROGRAM_POINT_SIZE`를 사용하는 `glEnable` 참조) 이 값이 점을 래스터화 하는데 사용된다. 그렇지 않으면`glEnable(GL_PROGRAM_POINT_SIZE)` 인 경우, 셰이딩 언어 내장 변수 `gl_Point..
2025.12.30
[C++] 전역 변수, 내부 연결, 외부 연결, 헤더 include 주의점
전역 변수, 내부 연결, 외부 연결전역 변수전역 변수는 가급적 사용하지 않는 것이 좋지만, 부득이하게 사용해야 하는 경우가 발생하는데 그때 그때 상황이 다르다. 결국 어떻게, 사용해야할지는 프로그래머 본인들이 결정해야 한다. 전역 변수의 name hiding전역 변수와 똑같은 이름으로 선언된 지역 변수가 있으면 name hiding이 수행되어, 지역 변수가 우선적으로 사용된다. 만약 전역 변수의 값에 대해 접근하고 싶으면 `::` global scope operator를 통해 전역 변수에 접근할 수 있ㄷㅇ아.#include using namespace std;// name hiding int value = 123;int main(){ cout Linkage지역 변수의 경우 linkage가 없다..
2025.12.20
[C++] 함수 내의 static 변수 선언
staticstatic 의미를 이해할 때, C언어를 만든 사람입장(컴퓨터 구조, 어셈블러)에서 보면 이해하는게 조금 쉽다. static 변수는 os로부터 받은 "메모리"가 정적으로 선언된다는 것이 static이라는 것이다. 동적할당에 대비하여 생각하면 더 와닿을 것이다. 함수 내의 static 변수 선언static으로 함수 내의 변수가 선언되면 해당 함수 영역에서 변수가 선언될 때 같은 메모리를 쓰고, 초기화를 한 번 밖에 안한다.void doSomething(){ static int a = 1; ++a; cout doSomething()함수를 몇 번 호출하고 VS의 디버거를 통해 함수 내의 선언된 변수 a를 살펴보면, 함수 스코프에서 나와도 조사식에 값이 남아있는 것을 볼 수 있다. (F11이 아닌..
2025.11.30
[C++] int8_t, int_least8_t and int_fast8_t 차이
int8_t, int_least8_t and int_fast8_t 차이해당 차이점은 Carl Norum이 인용한 C99 표준의 섹션에 정의되어있다. 하지만 예제를 통해 이해하는 것이 도움이 될 수 있다. 우리가 36-bit system에 대한 C컴파일러를 가지고 있다고 가정해보자. `char` = 9bits, `short`=18bits, `int`=36bits, `long` = 72 bits 라면,`int8_t`는 존재하지 않는다. 이는 패딩없이 정확히 8bit를 가진다는 제약을 만족시키지 못하기 때문이다.`int_least8_t`는 `char`의 typedef이다. `short`나 `int`가 아니다. 표준은 최소 8bit를 가지면서 가장 작은 타입을 요구하기 때문이다.`int_fast8_t`는 무엇이..
2025.10.05
[C++] 변수 초기화 방식
Copy Initializationint a = 123; Direct Initializationint a(123); Unifrom Initializationint b {123}; direct와 unifrom 초기화는 사용자 정의 데이터 타입을 초기화 할 때 많이 사용한다. 최근에는 uniform 초기화를 권장한다는 소리가 있다. 이는 uniform 초기화 방식이 더 엄격하기 때문이다. 예를 들어, Direct 초기화 방식을 사용하면,#include using namespace std;int main(){ int a(3.14); return 0;} 에러가 아닌 warning 메시지만 띄운다. 출력 또한 3으로 잘된다. 이는 Copy 초기화 방식도 동일하다. 하지만, unifrom으로 초기..
2025.09.25
[C++] 데이터 타입의 크기 지정 방식과 ABI
데이터 타입의 크기C++에서 기본 데이터 타입의 크기는 언어 표준에서 최소 크기만 보장하고, 실제 몇 바이트를 사용할지는 컴파일러와 CPU 아키텍처가 결정한다. 이 표를 자세히 보면 `char`을 제외하고는 기본 유형 준 표준 크기가 지정된 유형이 없다. 이는 타입의 크기가 결정되지 않은 것은 아니고, 모든 컴파일러와 머신에 걸쳐 표준 크기가 존재하지 않다는 것을 의미한다. 그래서 컴파일러가 타입의 크기를 결정한다. 보통 16bit CPU면 `int`는 2byte이고, 32bit CPU이면 `int`는 4byte이다. 다만 64bit CPU라고 `int`가 8byte가 되진 않는데, 이처럼 컴파일러 개발자가 적절하다 싶은 데이터 크기를 지정하여 구현한다(물론 ABI는 맞추어야 함). 이런 타입 크기 지..
2025.09.24
[C++] 전처리기, 매크로
#include using namespace std;#define MY_NUMBER "Hello, World!"#define MAX(a, b) ((a>b) ? a : b)int main(){ cout 여기서 MAX(a, b) 꼴은 함수처럼 보이지만 (a, b)가 함수의 파라미터처럼 취급되는건 아니다. 그저 치환당할 대상의 자리를 표시하는 정도이고, 문자열 치환으로 취급한다. 그래서 실제 함수 호출처럼 스택에 값 복사, 타입 검사 등이 발생하지 않고 그냥 코드를 복사해서 붙여 넣는 것이다. 예전에는 속도가 빠를 수 있다는 이유로 매크로 함수를 사용하는 경우가 많았지만, 요즘은 사용하지 않는 추세라고 한다. 이러한 `#define`, `#ifdef`와 같은 것들을 전처리기 지시문이라고 한다. 그리 매..
2025.09.21
[C++] 네임스페이스
네임스페이스 사용법#include namespace MySpace1{ int doSomething(int a, int b) { return a + b; }}int doSomething(int a, int b){ return a * b;}using namespace std;int main(){ cout namespace는 중첩해서 선언 및 사용할 수 있다.#include namespace MySpace1{ namespace test { int doSomething(int a, int b) { return a + b; } }}int doSomething(int a, int b){ retu..
2025.09.13
[C++] 전방 선언과 헤더 파일에 대한 고찰
전방 선언헤더 파일을 만들지 않고, include를 하지 않더라도 다음과 같이 전방 선언해서 다른 cpp 파일의 함수를 사용할 수 있다. 컴파일러는 main.cpp를 컴파일 할 때, 전방 선언된 함수를 보고 어딘가에 `add(int a, int b)` 함수의 정의가 존재할거라고 믿고 컴파일에 문제가 생기지 않는다. 컴파일러는 컴파일만하고, 그 뒤의 작업인 실행할 때 링킹해서 알아서 사용하라는 개념이다. main.cpp#include using namespace std;int add(int a, int b);int main(){ cout 그리고 사실, `int add(int a, int b)` 앞에 생략되어 있는 키워드가 하나 있다. 바로 `extern`이다. 즉, 원래는 ` extern int add..
2025.09.10