Предотвращение неподходящего станд.:: строковая инициализация с ПУСТЫМ символом константы* использующий g ++

Там любой g ++ опции, которые могут обнаружить неподходящую инициализацию станд.:: строка с ПУСТЫМ символом константы*?

Я был в процессе превращения некоторых международных полей в станд.:: строковые, т.е.:

struct Foo
{
   int id;
   Foo() : id(0) {} 
};

... превращенный:

struct Foo
{
   std::string id;
   Foo() : id(0) {} //oooops!
};

Я полностью пропустил плохую 'идентификационную' инициализацию с 0, и g ++ не дал мне предупреждений вообще. Эта ошибка была обнаружена во время выполнения (станд.:: строковый конструктор выдал исключение), но я действительно хотел бы обнаружить такой материал во время компиляции. Есть ли какой-либо путь?

10
задан pachanga 9 March 2010 в 08:59
поделиться

3 ответа

Я думаю, что на самом деле это неопределенное поведение и не проверяется компилятором. Вам повезло, что эта реализация вызывает исключение.

Однако вы можете избежать таких проблем, указав, что вы хотите инициализацию по умолчанию или нулевую инициализацию независимо от типа:

struct Foo
{
   X id;
   Foo() : id() {} //note empty parenthesis
};
5
ответ дан 3 December 2019 в 23:12
поделиться

Я не могу придумать способ обнаружить это во время компиляции, поэтому я написал функцию сборщика строк, которая правильно работает с нулевыми указателями:

//  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.

7
ответ дан 3 December 2019 в 23:12
поделиться

В GCC есть инфраструктура для выдачи именно такого предупреждения:

void foo(const char* cstr) __attribute__((nonnull (1)));

void bar() {
    foo(0);
}

при компиляции с -Wnonnull (что подразумевается -Wall) выдает:

warning: null argument where non-null required (argument 1)

Поэтому в принципе вы должны иметь возможность изменить соответствующий системный заголовок (или, лучше для экспериментов, изменить свою собственную копию $HOME/bits/basic_string. h и затем переопределить системный с помощью -isystem $HOME) подобным образом:

basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
    __attribute__((nonnull (1)));

Однако это не поможет, поскольку (по крайней мере, в 4.0.1) -Wnonnull не поддерживается в C++, и атрибут, по-видимому, игнорируется. Неясно, почему это так; возможно, было сочтено, что он плохо взаимодействует с перегрузкой или что-то в этом роде.

2
ответ дан 3 December 2019 в 23:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: