정적 채널
18 subscribers
29 photos
128 links
static의 채널입니다.
- 각종 프로그래밍 관련 정보
- 듣기 좋은 노래/음악
- 그 외 잡다한 것들

운영자 @kmc7468
이런 곳은 어떠세요? @static_gal @devroom_join @hail_cpp
Download Telegram
제목: inline 함수와 inline 변수

C++에는 inline 함수라는 기능이 있습니다. 함수를 선언할 때 inline 지정자를 붙여주면 그 함수는 inline 함수가 됩니다. inline 함수의 기본적인 의미는 컴파일될 때 inlining되는 함수입니다.

실제로 함수를 호출하는 동작은 다음과 같이 구현됩니다. 인수들을 스택에 push한 뒤, 새로운 스택 프레임을 만들고, 함수가 위치한 곳으로 점프합니다. 그 후 함수가 종료되면 다시 스택 프레임을 원래대로 되돌린 뒤 인수들을 pop하고, 호출자로 다시 점프해 돌아옵니다. 이 때문에 필연적으로 약간의 오버헤드가 발생할 수밖에 없습니다.

특히 과거, C/C++이 막 등장했을 시절에는 컴퓨터의 성능이 좋지 않아 이러한 오버헤드도 꽤 큰 성능 저하 요소 중 하나로 작용했었고, 때문에 inlining이라는 기법이 도입되었습니다. inlining은 함수의 호출을 위에서 설명한 과정으로 구현하는 것이 아니라, 함수의 본문을 해당 위치에 그대로 집어넣어 함수 호출 오버헤드를 없애는 기법입니다. 똑같은 함수 내용이 여러 번 반복되기 때문에 바이너리 크기가 커지는 문제 등이 있지만, 당시에는 함수 호출 오버헤드가 꽤 컸었기 때문에 많이 사용됐었습니다.

하지만 현재에는 상황이 조금 많이 다릅니다. 컴퓨터의 성능이 비약적으로 발전되어 일반적인 경우에는 함수 호출 오버헤드를 신경 쓸 필요가 없어져 버렸죠. 또, 컴파일러의 최적화 기술 역시 크게 발전해 inline 지정자의 유무에 관계없이 컴파일러가 적절히 판단해 inlining이 필요한 함수는 inlining을, 그렇지 않은 함수는 inlining하지 않도록 되었습니다(물론 지금도 컴파일러가 inline 지정자를 완전히 무시하거나 하지는 않습니다. 약간의 힌트 정도로 사용되고 있죠.). 그래서 inline 지정자를 사용하는 의도가 과거와는 조금 달라졌는데요.

inline 함수는 함수를 호출한 곳에 inlining을 해야 했기 때문에 컴파일러가 모든 번역 단위에서 해당 함수의 본문을 볼 수 있어야 했습니다. 일반적인 함수는 선언을 헤더 파일, 정의를 소스 파일에 하는데, inline 함수는 선언과 정의를 동시에 헤더 파일에서 해야 했습니다(엄밀하게 말하자면 꼭 그런 것은 아니지만, 논외로 하겠습니다.). 일반적인 함수는 헤더 파일에 선언했을 경우 반드시 소스 파일에 정의를 해야 하기 때문에(헤더 파일에 선언과 정의를 동시에 하면 링크 오류가 발생합니다.) 헤더 파일에서 함수의 선언과 정의를 동시에 하고 싶을 때 inline 함수의 특성을 이용해 inline 함수로 선언하면 헤더 파일에서 함수의 선언과 정의를 동시에 할 수 있게 됩니다. 따라서 최근에는 이러한 의도로 inline 지정자를 사용하는 경우가 많아지고 있습니다.

한편, 이러한 맥락에서 inline 변수가 C++17에 새롭게 도입되었습니다. 단순히 inline 함수가 inlining을 하는 함수라는 뜻만 알고 있었다면 inline 변수의 의도를 파악하기가 쉽지 않습니다. 그러나 현재에 inline 지정자가 헤더 파일에서 선언과 정의를 동시에 하고 있다는 맥락을 알고 있다면 inline 변수의 의도를 쉽게 파악할 수 있습니다. 바로 헤더 파일에서 변수를 선언과 동시에 정의하기 위해서입니다. 전역 변수, class 내에 있는 static 멤버 변수 등은 선언을 헤더 파일에서 할 경우 반드시 소스 파일에서 정의해 줘야 합니다. 그러나 C++17에 도입된 inline 변수 문법을 사용하면 선언과 동시에 정의를 할 수 있습니다. 굉장히 편리한 문법이죠.

몇몇 분들은 inline 지정자가 inlining을 하는 함수라는 의미에서 이름이 붙여졌기 때문에 inline 변수에서 inline이라는 지정자를 사용한 것을 억지 키워드 재활용이라고 생각하실 수도 있지만, 선언과 정의를 동시에 한다는 의미에서 접근하면 이상한 의미는 아닙니다.

#C #Cpp
코로나바이러스감염증-19가 빠르게 확산됨에 따라 전국 유치원, 초중고교의 개학이 1주일 연기되었습니다. 손씻기, 마스크 착용, 외출 자제 등으로 여러분들의 건강을 지킬 수 있습니다.
Channel photo updated
ShitVM 소개
가벼운 가상머신이라는 컨셉으로 개발 중인 범용VM입니다!
#Cpp #ShitVM
ShitVM 0.1.0
파이썬보다 더 빠른 가상머신!
#Cpp #ShitVM
ShitVM 0.2.0
구조체, 포인터 추가!
#Cpp #ShitVM
C++에서 지수 연산자를 사용해 보세요!
#Cpp
정적 채널
C++에서 지수 연산자를 사용해 보세요! #Cpp
#include <cmath>

template<typename T>
struct Base {
T Value;
};
template<typename T>
struct DoExp {
T Value;
};
template<typename T>
struct Exp {
T Value;

constexpr DoExp<T> operator*() const noexcept {
return { Value };
}
};

constexpr Exp<unsigned long long> operator""_e(unsigned long long v) noexcept {
return { v };
}
constexpr Exp<long double> operator""_e(long double v) noexcept {
return { v };
}

unsigned long long operator*(unsigned long long b, DoExp<unsigned long long> e) noexcept {
return std::pow(b, e.Value);
}
long double operator*(long double b, DoExp<long double> e) noexcept {
return std::pow(b, e.Value);
}
소스코드입니다. 아쉽지만 지수와 곱셈의 연산자 우선 순위가 같아서 괄호를 적절히 활용해야 할 필요가 있을 수도 있습니다.
#Cpp
ShitVM 0.3.1
배열, 동적 할당, GC 추가!
#Cpp #ShitVM
ShitGraph
그래프 그려주는 프로그램을 개발하고 있습니다!
#Cpp #ShitGraph #그래프
MSVC2019 기준으로, std::chrono::system_clockstd::chrono::high_resolution_clock 의 정밀도가 같습니다.

system_clock 은 내부적으로 GetSystemTimePreciseAsFileTime 함수를, high_resolution_clock 은 내부적으로 QueryPerformanceCounter 함수를 사용합니다. 그런데 GetSystemTimePreciseAsFileTime 함수는 내부적으로 QueryPerformanceCounter 함수를 사용해 구현됩니다. 따라서 system_clockhigh_resolution_clock 의 정밀도가 같습니다.

그래서 두 clock 의 차이는 시스템 시간을 변경했을 때에도 시간의 변화를 제대로 계산할 수 있는지 없는지 밖에 없습니다. system_clock 의 경우에는 시스템 시간을 변경하면 시간의 변화를 제대로 계산할 수 없지만(GetSystemTimePreciseAsFileTime 함수는 시스템 시간을 가져오는 함수이기 때문), high_resolution_clock 의 경우에는 시스템 시간을 변경해도 시간의 변화를 제대로 계산할 수 있습니다.

#Cpp #Microsoft #MSVC #모던Cpp #프로그래밍
MSVC Debug 모드에서 세그폴트가 발생했을 때, 메모리에 저장된 값으로 어떤 메모리 영역에 액세스했는지 알아낼 수 있습니다.
- 0xCCCCCCCC: 초기화되지 않은 지역 변수
- 0xCDCDCDCD: 초기화되지 않은 힙
- 0xDDDDDDDD 또는 0xFEEEFEEE: 할당 해제된 힙
- 0xFDFDFDFD: 할당된 공간을 벗어난 힙
#C #Cpp #MSVC #Windows #프로그래밍