1

私は構造体リファクタリング時にstruct safeの集約初期化が行われていますか?

SomeStruct 
{ 
    double y; 
    double x; 
}; 

を持っていると私はどこか

SomeStruct s{1,2}; //y=1 x=2 

ようにそれを初期化し、私がするので

SomeStruct 
{ 
    double x; 
    double y; 
    double z; 
}; 

に私の構造体を並べ替えた場合、私のコードは静かに破ることができると思われる場合今度はSomeStruct s{1,2}は、x = 1、y = 2、z = 0を意味します。

編集: 引数は、コンストラクタが同じ問題を抱えているということですが、現実のIDEを使用している場合は、引数の名前とオーダーを一般的に見ることができます。

これまで言及したことは誰も見たことがありませんが、データのレイアウトを決して変更しないことが確実な場合は、このような集約初期化を安全に使用できるようです。それはまれな状況でしょうか?「非同質の構造体に集約初期化を使用しない」という暗黙のルールがありますか?

+0

コンストラクタは実際に同じ問題を抱えています。これは初期化よりも型の問題です。 –

+0

しかし、新しいオブジェクトをコンストラクタに追加すると、新しいオブジェクトがない場合はコードがコンパイルされません。問題では、コードがコンパイルされ、誰もエラーがあると認識することはありません。 – Ventu

+0

@Ventu:そうですが、同じタイプのフィールドを並べ替えたり、コンストラクタパラメータを並べ替えると、静かな変更を導入することができます。 –

答えて

0

リファクタリング時のstruct safeの集約初期化はありますか?

このコンテキストでは、「安全」をどのように定義するかによって異なります。そして、どのようなリファクタリングが行われますか?

私のコードは、静かに破ることができるようだ...今ので、SomeStruct s{1,2}は完全にOKであるかもしれないx=1, y=2, z=0

ことを意味します。なぜzを0に初期化してはならないのですか?あなたはそれが何を表すかを知るまで、壊れているかどうかは分かりません。

これは、あなたがクラスに対して行うことができるより良い変化の1つです。メンバーの並べ替えなどの異なる変更は、依存コードの変更を確実に必要とします。

データのレイアウトを決して変更しないことが確実な場合は、このような集約初期化を安全に使用できるようです。

また、唯一の変更が値の初期化に適している新しいメンバーであると予想される場合。 (Cは指定されたイニシャライザをサポートしていますが、メンバーの順序の変更にも対応しています。残念ながら、C++ではありません)。

また、集計の初期化を見つけて更新するのに問題が見つからない場合は、この可能性は、集約を変更するたびに存在することを知っておく必要があります。

実際、コンストラクタは、ユーザーをメンバーの変更から切り離す一種の「実装ファイアウォール」を提供するのは事実です。新しいメンバのようないくつかの変更は、コンストラクタへの変更を促すかもしれませんが、コンストラクタの引数が欠けていると、コンパイルが役に立ちます。

「非同質の構造体に集約初期化を使用しないでください」という暗黙のルールがありますか?

あなたと私が考えた限り例外ではありません。また、同質性は異ならない。

公開 APIを設計するときは、クラスのレイアウトを石に設定するか、メンバーを非公開にしてコンストラクタを提供するかを検討する必要があります。内部APIの場合は、クラスのすべての使用をすばやく調べることができます。 -Wmissing-field-initializers-Wextraでは有効):


GCCはあなたが記述の正確な状況を解決し、警告オプションがあります。メンバーイニシャライザを提供する場合は警告が表示されますが、すべてではありません。

+0

"メンバーの順序を変更するなど、異なる変更は、依存コードの変更をより確実に必要とします。私は実際に主な問題であるxとyを並べ替えています。おそらく、zを追加すると疑問が混乱しました。私は質問を編集して、並べ替えを_only_言及します。 – JoeTaicoon

+0

@JoeTaicoonは、新しいフィールドの追加に関する質問を削除しません。それは私の答えの一部を時代遅れにするでしょう。しかし、並べ替えについての編集を自由に追加してください。私の答えはすでに両方のケースをカバーしています。 – user2079303

関連する問題