より効果的なC++では、混合配列と多相の混合が悪い考えです。混合配列と多相のコンパイラの警告
class Base {
public:
Base(int y) : a(y) {}
int a;
};
class D : public Base {
public:
D(int w, int y) : Base(y), c(w) {}
int c;
};
std::ostream& operator<<(std::ostream& os, const Base &obj)
{
os << obj.a << std::endl;
return os;
}
// This function will work perfectly well if i pass in a `Base` array,
// but if i pass in `D` array we are going to run into some problems.
// Namely that `arr[i+1] = &arr[i] + sizeof(Base)` will not progress
// the array correctly for a `D` array.
void printArray(const Base arr[]) {
for (int i = 0; i < 5; ++i) {
std::cout << arr[i];
}
}
int main() {
D arr[5] = { D(0, 10), D(1, 11), D(2, 12), D(3, 13), D(4, 14)};
printArray(arr); // This compiles without complaint! I understand that the
// conversion is legal, but it seems like a warning
// about this would be a good idea.
}
注:例えばのために私はこれは悪いデザインですが、ポイントを説明するために知っています。
ここでの問題は、我々は我々が正しい量で配列の要素を進行しません印刷する配列を反復処理するとき、私は上記の持っているように、これら二つを混合する場合(つまり、私たちはsizeof(Base)
の代わりsizeof(D)
によって移動することです)。
10
0
11
1
12
を(と私は、このようなoperator<<
の呼び出しは、おそらくUBであると推測しています):これは出力になります。
g++ -std=c++1y -Wall -Weffc++ -pedantic main.cpp
でコンパイルすると、警告またはエラーは表示されません。
- このシナリオで警告を示すために有効にできるコンパイラフラグはありますか?
- もしそうでなければ、どうですか?
「2)の答えは、コンパイラが実装するために「警告」が必須ではないということです。 g ++の実装者に警告を追加するように頼むことができます(まだ存在していない場合)。ただし、これらの警告はどの標準でも強制されません。 – PaulMcKenzie
@PaulMcKenzie、本当ですが、GCCはその警告を上回り、これを検出するのに技術的な難しさがあるのでしょうか? –
コンパイラをまとめたエンジニアに尋ねる必要があります。答えは、「それは良いアイデア」から「私たちは時間がありません」から「それはすでに存在しています」のいずれかになります。 – PaulMcKenzie