referencias que normas formato for estilo ejemplos cse citas bibliograficas apa c++ language-lawyer

c++ - normas - que es el estilo cse



Clase que contiene una referencia a sí misma. (3)

Revisando el borrador estándar (n3242), encontré esta oración en la Cláusula 9.2 (el énfasis es mío):

Los miembros de datos no estáticos (9.4) no tendrán tipos incompletos. En particular, una clase C no debe contener un miembro no estático de la clase C, pero puede contener un puntero o referencia a un objeto de la clase C.

De esto sostengo que está bien definir una clase como esta:

class A { public: A(A& a) : a_(a){ } private: A& a_; };

Luego en la cláusula 8.3.2 encontré lo siguiente:

Una referencia se inicializará para referirse a un objeto o función válido

Pregunta 1: ¿Está permitido definir un objeto de este tipo pasando su nombre como referencia?

A a(a);

¿O esto provocará un comportamiento indefinido?

Pregunta 2: En caso afirmativo, ¿cuáles son las partes de la norma que permiten la inicialización de la referencia de un objeto aún por construir?

Pregunta 3: Si no, ¿significa que la definición de clase A está bien formada pero no se puede crear un primer objeto sin desencadenar UB? En este caso, ¿cuál es la razón detrás de esto?


"objeto válido" no se define en ninguna parte del estándar, pero pretende significar una región de memoria con el tamaño y la alineación adecuados que pueden contener un objeto del tipo especificado. Simplemente significa excluir las referencias a cosas como punteros nulos no referenciados, regiones de memoria desalineadas, etc. Un objeto sin inicializar es válido.

Hay un problema abierto para aclarar la redacción, CWG 453 .


Desde n1905, 3.3.1.1.

El punto de declaración para un nombre es inmediatamente después de su declarador completo (cláusula 8) y antes de su inicializador (si lo hubiera), excepto como se indica a continuación.

[Ejemplo:
int x = 12;
{int x = x; }

Aquí la segunda x se inicializa con su propio valor (indeterminado).

—En ejemplo]

Mi énfasis (corríjame si me equivoco): en su ejemplo -

A a(a);

es equivalente a -

A a = a; // Copy initialization

Por lo tanto, de acuerdo con el estándar a se inicializa con su propio valor indeterminado. Y el miembro mantiene una referencia a uno de esos valores indeterminados.


n3337 § 3.8 / 6

De manera similar, antes de que haya comenzado la vida útil de un objeto, pero después de que se haya asignado el almacenamiento que ocupará el objeto o, después de que haya finalizado la vida útil de un objeto y antes de que el almacenamiento que ocupa el objeto se reutilice o libere, cualquier valor de glualidad que se refiera El objeto original puede ser usado pero solo de manera limitada. Para un objeto en construcción o destrucción, ver 12.7. De lo contrario, dicho glvalue se refiere al almacenamiento asignado (3.7.4.2), y el uso de las propiedades del glvalue que no dependen de su valor está bien definido. El programa tiene un comportamiento indefinido si:

- se aplica una conversión de lvalue a rvalue (4.1) a dicho glvalue,

- el valor de glival se usa para acceder a un miembro de datos no estáticos o llamar a una función de miembro no estático del objeto, o

- el valor de glvalue se convierte implícitamente (4.10) en una referencia a un tipo de clase base, o

- el valor de glvalue se utiliza como operando de static_cast (5.2.9) excepto cuando la conversión es, en última instancia, a cv char & or cv unsigned char &, o

- el valor de glvalue se utiliza como el operando de un dynamic_cast (5.2.7) o como el operando de typeid.

Por lo tanto, para responder a sus preguntas:

Pregunta 1: ¿Está permitido definir un objeto de este tipo pasando su nombre como referencia?

Sí. Usar solo la dirección parece no violar esto (al menos para una variable colocada en la pila).

A a(a);

¿O esto provocará un comportamiento indefinido?

No.

Pregunta 2: En caso afirmativo, ¿cuáles son las partes de la norma que permiten la inicialización de la referencia de un objeto aún por construir?

§ 3.8 / 6 (arriba)

La única pregunta que queda es cómo esto corresponde a

Se debe inicializar una referencia para referirse a un objeto o función válida .

El problema está en el término objeto válido . Porque el § 8.3.2 / 4 dice que

No se especifica si una referencia requiere o no almacenamiento

Parece que el § 8.3.2 es problemático y debe ser reformulado. La confusión condujo al cambio propuesto en el documento C ++ Standard Core Language Active Issues, Revisión 87 de fecha 20.01.2014:

Se debe inicializar una referencia para referirse a un objeto o función.

Cambie 8.3.2 [dcl.ref] párrafo 4 como sigue:

Si un lvalor al que está directamente vinculada una referencia no designa un objeto o función existente de un tipo apropiado (8.5.3 [dcl.init.ref]), ni una región de memoria de tamaño y alineación adecuadas para contener un objeto del tipo de referencia (1.8 [intro.object], 3.8 [basic.life], 3.9 [basic.types]), el comportamiento es indefinido.