Подтвердить что ты не робот

Аргумент по умолчанию, gcc vs clang

Код выглядит так:

struct Foo {
    Foo(const char *);
};

Foo::Foo(const char *str = 0)
{
}

VS 2013 и gcc 4.8.0 принимают такой код, в то время как clang 3.3 отклоняет такой код с помощью:

ошибка: добавление аргумента по умолчанию в redeclaration делает этот конструктор конструктором по умолчанию

кто прав от стандартной (С++ 03 и С++ 11) точки зрения?

Примечание:

Мне нравится выбор clang, но я собираюсь сообщить об ошибке gcc и visual studio, и если это неверно со стандартной точки зрения, это помогает убедить разработчиков компиляторов исправить эту проблему.

НКУ

Я описал проблему здесь: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58194

Но не повезло, они приостанавливают исправление ошибок до тех пор, пока проект не станет стандартным.

4b9b3361

Ответ 1

Это обсуждалось в списке рассылки Clang и было представлено как Отчет о дефектах Основной выпуск 1344.

Из обсуждения в списке рассылки:

Идея состоит в том, что наличие определенных специальных элементов влияет на ядро свойства типа класса, например, будь то POD или тривиально копируемый. При решении этих свойств не требуется целая программа знание; для нас важно уметь выводить их из определение класса. Действительно проблематичным является обращение "нормальный" конструктор в конструктор копирования или перемещения, добавив значение по умолчанию аргументы, но IIRC, представляющий конструктор по умолчанию, также был проблематичным.

Исправление состоит в том, что вы должны поместить аргумент по умолчанию в начальный объявление конструктора.

В последний раз это обсуждалось РГ21 на совещании в Блумингтоне. Примечания от есть:

"Консенсус: сделайте это плохо сформированным, как было предложено в рецензии. выпуск 1344. Приоритет 0, подготовка Дуга."

Итак, CWG согласилась (в принципе), что это должно быть плохо сформировано.

TL; DR Clang прав, когда дефект фиксируется (не уверен, что это может официально произойти только с С++ 14, или если такие решения Комитета также могут быть сделаны ретроактивно на С++ 11)

Ответ 2

Я бы сказал, что КЛАНГ прав. В стандарте говорится (12.1.5 для старых и новых версий стандарта):

Конструктор по умолчанию для класса X является конструктором класса X, который можно вызывать без аргумента

Добавление значения по умолчанию к единственному аргументу конструктора, безусловно, позволяет вызывать его без аргументов, тем самым делая его по умолчанию. Кроме того, 8.3.6 говорит (акцент мой):

Выражение аргумента по умолчанию должно быть указано только в Параметр декларирование придаточного объявления <... >

Ответ 3

У вас есть декларация и определение. В вашей декларации вы не имеете значения по умолчанию, а в вашем определении - значение по умолчанию. Фактически подпись декларации очень похожа на подпись определения, но не то же самое. Я считаю, что строгость - хорошая идея, поэтому я считаю, что лучше обеспечить, чтобы объявление было таким же, как определение.