g ++를 사용하여 null const char*를 사용한 부적절한 std :: 문자열 초기화를 피하십시오.
문제
a g ++ 옵션이있는 옵션이 널 const char*로 std :: 문자열의 부적절한 초기화를 감지 할 수 있습니까?
나는 int 필드를 std :: 문자열로 바꾸는 과정에있었습니다.
struct Foo
{
int id;
Foo() : id(0) {}
};
...로 전환:
struct Foo
{
std::string id;
Foo() : id(0) {} //oooops!
};
0으로 BAD 'ID'초기화를 완전히 간과하고 G ++는 전혀 경고를주지 않았습니다. 이 오류는 런타임에 감지되었지만 (std :: 문자열 생성자는 예외를 던졌습니다) 컴파일 시간에서 그러한 것들을 감지하고 싶습니다. 어떤 방법이 있습니까?
해결책
나는 그것이 실제로 정의되지 않은 동작이며 컴파일러에 의해 점검되지 않았다고 생각합니다. 이 구현이 예외를 던진다는 것이 운이 좋다.
그러나 타입 공유 방식으로 기본 또는 제로 시작을 원하는 것을 지정하여 이러한 문제를 피할 수 있습니다.
struct Foo
{
X id;
Foo() : id() {} //note empty parenthesis
};
다른 팁
컴파일 타임에서 이것을 감지하는 방법을 생각할 수 없으므로 널 포인터를 제대로 다루는 문자열 빌더 기능을 작성했습니다.
// FUNCTION : safe_string(char const* pszS)
// PARAMATERS : pszS source string to build a string from (may be NULL or 0-length)
// DESCRIPTION : Safely builds a string object from a char*, even a NULL pointer
// RETURNS : string
template<class C>
inline basic_string<C> safe_string(const C* input)
{
if( !input )
return basic_string<C>();
return basic_string<C>(input);
}
문자열을 만들 때마다 이것을 사용하고 입력이 null 일 가능성이 있습니다.
GCC에는 이러한 종류의 경고를 정확히 생성하기위한 인프라가 있습니다.
void foo(const char* cstr) __attribute__((nonnull (1)));
void bar() {
foo(0);
}
컴파일 된 경우 -Wnonnull
(암시된다 -Wall
) 제작 :
warning: null argument where non-null required (argument 1)
따라서 원칙적으로 관련 시스템 헤더를 수정할 수 있어야합니다 (또는 실험에 더 나은 경우 자신의 $ 홈/비트/Basic_string.h 복사 한 다음 시스템을 재정의하십시오. -isystem $HOME
) 마찬가지로 :
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
__attribute__((nonnull (1)));
그러나 이것은 (적어도 4.0.1에서) 도움이되지 않습니다. -Wnonnull
C ++에서는 지원되지 않으며 속성은 분명히 무시됩니다. 이것이 왜 그렇게되는지 분명하지 않습니다. 아마도 그것은 과부하 나 무언가와 심하게 상호 작용한다고 느꼈을 것입니다.