[CPP] Visual Studio 사용 시 불편한 점 해결
1. sprintf 사용 시 계속 sprintf_s 를 사용하라고 나온다.
문제 발생 이유 :
sprintf 는 문자열에 무언가 집어넣고 싶을 때 사용한다는 것을 알고 있을 것이다.
sprintf 는 아래와 같다.
요컨대, char 버퍼에다가 Printf format string 을 넣으며, ...을 통해 다른 인자들이 들어올 수 있음을 의미한다.
따라서 우리는 이를 아래와 같이 사용한다.
그런데 이 코드를 보면 의문이 하나 생긴다.
만약 입력되는 문자열이 버퍼 사이즈보다 크면 어떻게 되는거지?
그렇다. sprintf 에서는 이에 대한 고려가 되어있지 않다.
그렇기 때문에 오버플로우로 인한 잠재적인 메모리 침범 문제가 발생할 수 있다.
따라서 컴파일러에서 이 sprintf 대신 sprintf_s 를 사용할 것을 권장하기 때문에 생기는 문제이다.
해결 방법 :
1. sprintf_s 를 사용하면 된다.
sprintf_s 는 여기에 BufferCount 를 추가한 형태이다. 따라서 버퍼 사이즈만큼만 데이터가 들어가게 되어 메모리 침범에 대해 해결하였다.
2. 프로젝트 설정을 변경한다 (VS)
그럼 sprintf 는 영영 쓸 수 없나요?
아니다. VS 프로젝트에서 설정을 변경함으로써 해결할 수 있다.
'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead.
To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
sprintf 를 사용한 채로 컴파일 하려고 하면 위와 같이 안전하지 않으니까 sprintf_s 를 쓰는건 어때요...?(강제) 라고 컴파일러가 물어본다. 그러면서, 이 경고를 없애려면 _CRT_SECURE_NO_WARNINGS 를 사용하라고 한다.
어떻게 사용하는데...?
이렇게 위와 같이 C/C++ 전처리기 옵션에 들어가서 _CRT_SECURE_NO_WARNINGS 를 정의하면
이 경고를 발생시키지 않게 된다.
의문점 :
근데 함수 정의를 보러 갔을때 나온 __CRTDECL 이런건 뭘까?
참조를 타고 들어가면, 이렇게 __cdecl 이라는 것을 정의하는 매크로임을 알 수 있는데,
이는 C/C++ 컴파일러에서 사용하는 함수 호출 규칙(Calling Convention) 중 하나라고 한다.
사실 우리가 사용하는 메인 함수는 실제로 아래와 같은데,
이는 함수 이름 앞에 아무런 규칙을 설정하지 않으면 자동으로 기본 규칙(__cdecl) 을 사용하기 때문이라고 한다.
이 규칙들은 호출자 함수(Caller)가 피호출자 함수(Callee)를 호출할 때의 메모리 관리를 어떻게 할 것인지에 대한 것들인데, 보다 자세한 내용은 아래의 블로그를 참고하는 것이 좋을 것 같다.