Programming/CPP

[CPP] Visual Studio 사용 시 불편한 점 해결

트릭시 2024. 8. 4. 23:07
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) 중 하나라고 한다.

실제로 C/C++ 고급 탭을 확인해 보면 여러 Calling Convention 이 있음을 확인할 수 있으며, 기본으로 __cdecl 이 선택되어 있다.

 

사실 우리가 사용하는 메인 함수는 실제로 아래와 같은데,

이는 함수 이름 앞에 아무런 규칙을 설정하지 않으면 자동으로 기본 규칙(__cdecl) 을 사용하기 때문이라고 한다.

이 규칙들은 호출자 함수(Caller)피호출자 함수(Callee)를 호출할 때의 메모리 관리를 어떻게 할 것인지에 대한 것들인데, 보다 자세한 내용은 아래의 블로그를 참고하는 것이 좋을 것 같다.

 

https://mattlee.tistory.com/77

https://blog.naver.com/work1989/221275066623