2012-03-26 3 views
7

я уменьшил это:Is `X x = x = X();` legal C++?

struct A 
{ 
    int * x; 
    A() : x(x = new int()) 
    { 
    } 
}; 

к следующему:

int m = m = 3; 
//or 
struct X; 
//... 
X x = x = X(); 

Кажется законным для меня. Я не понимаю, почему вы хотите это сделать, но это законно? Есть случаи, когда вы захотите это сделать (а не дело int, я понимаю, что это абсолютно бесполезно)?

+6

Вы понимаете, что 'y = A()' вызывает 'operator =' для uninitializated variable? –

+0

@ R.MartinhoFernandes no. Ухаживать за расширением? –

+6

Я не понимаю, где вы говорите, я уменьшил это (пример) до (совершенно другой пример). –

ответ

17

Это зависит от того, как вы определяете «правовые». Это будет компиляция; это не означает, что он будет работать.

До полного заявления X x = ... исполняет, x неинициализирован. Это еще не X. Поэтому выполнение x = X() означает создание временного X и вызывает X::operator=(const X&) на неинициализированной переменнойx.

Вызов функции на экземпляре не POD class, который не был инициализирован (кто еще не был вызван конструктором), дает неопределенное поведение. Если X - это тип POD (или тривиальный в C++ 11), то он будет работать. Но в противном случае нет.

+0

Почему существует разница между POD и не-POD типы? Я не знаком с этой частью стандарта. Можете ли вы предоставить цитату? –

+0

@LuchianGrigore Поскольку типы POD имеют побитовую семантику копирования. –

+1

@ LuchianGrigore: Есть причина, по которой я связан с этим вопросом, когда я сказал «класс POD». Вы должны это прочитать. –

10

Это синтаксически законный, но приведет к неопределенному поведению во время выполнения. В заявлении, как:

X x = x = X(); 

второй = это назначение, и он присваивает неинициализированного переменной. (Первый = - это просто синтаксис для обозначения того, что последующее следует использовать для инициализации копирования, это не присвоение.)

0
int m = m = 3; 
//or 
struct X; 
//... 
X x = x = X(); 

то будет законным (если вы определение структуры, который называется X, но ваша структура называется A, также вам не нужно писать структуру, состоящие из C++), но как это неопределенное поведение.

x(x = new int()) является законным, но также имеет неопределенное поведение.

+0

«также вам не нужно писать struct с C++ «Я просто сказал, что это так, люди знают, что это была структура. –

1

Это юридический синтаксис. X имеет собственное определение. Ситуация, при которой вы можете объект ссылаться на сам по себе круговыми связные списки, вдоль линий:

struct Node { 
    Node(Node *pNext_) : pNext(pNext_) { 
    } 
    // ... 
    Node *pNext; 
}; 

Node empty(&empty }; 

Этот пустой список состоит из фиктивного узла, который имеет ссылку на себя. Это хорошо определено и полезно. Обратите внимание, что мы берем адрес пустой, который является законным, даже если Node является не-POD и еще не сконструирован. Я не думаю, что предоставление задания, как в вашем примере int m = m = 3;, прямо полезно, но язык не позволяет моему, а не разрешать ваши.

Чтобы увидеть, как это переносится на конструкторы членов, считает:

struct A { 
    Node list; 
    A() : list(&list) {} 
} 

После того, как имя находится в области видимости, что позволяет присваивание и от этого становится возможным тоже.

+0

Ваш пример совершенно другой. –

+0

@LuchianGrigore Вопрос был в том, «Есть ли случаи, когда вы захотите это сделать (не в случае int, я понимаю, что это абсолютно бесполезно)?» Другие ответы обсуждали законность, но ничего не говорили о том, почему это может быть полезно. Мой ответ затрагивает эту часть вопроса. Вопрос признает, что его точные примеры бесполезны; несколько иной пример был неизбежен. Я обсуждаю, как перейти от моего примера к одному в вопросе (т. Е. После того, как имя в области присвоения тоже становится законным). – Brangdon

+0

Хорошо, но редактирование изменяет весь ответ. В оригинале не было объекта, инициализированного самим. –

Смежные вопросы