8

次のテストケースを検討してください (LLVM ソースから縮小):

//% cat foo1.cpp

#include <memory>
namespace {
class A {
  int i;
};
}
class G {
  std::unique_ptr<A> foo() const;
};
std::unique_ptr<A> G::foo() const { return std::make_unique<A>(); }

//% cat foo2.cpp

#include <memory>
namespace {
class A {
  bool a;
};
}
class H {
  std::unique_ptr<A> bar() const;
};
std::unique_ptr<A> H::bar() const { return std::make_unique<A>(); }

これは 1 つの定義規則に違反していますか?

gcc-6 は現在、次のように考えています。

 ~ % g++ -flto -shared -std=c++14 foo1.cpp foo2.cpp

/home/trippels/gcc_test/usr/local/include/c++/6.0.0/tuple:187:72: warning: type ‘struct _Base’ violates one definition rule [-Wodr]
       typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base;
                                                                         ^
/home/trippels/gcc_test/usr/local/include/c++/6.0.0/tuple:187:72: note: a different type is defined in another translation unit
       typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base;
                                                                         ^
/home/trippels/gcc_test/usr/local/include/c++/6.0.0/tuple:147:13: note: the first difference of corresponding definitions is field ‘_M_head_impl’
       _Head _M_head_impl;
              ^
/home/trippels/gcc_test/usr/local/include/c++/6.0.0/tuple:147:13: note: a field of same name but different type is defined in another translation unit
       _Head _M_head_impl;
              ^
foo1.cpp:3:7: note: type ‘struct A’ defined in anonymous namespace can not match type ‘struct A’
 class A {
        ^
foo2.cpp:3:7: note: the incompatible type defined in anonymous namespace in another translation unit
 class A {
        ^
/home/trippels/gcc_test/usr/local/include/c++/6.0.0/tuple:598:40: warning: type ‘struct _Inherited’ violates one definition rule [-Wodr]
       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
                                         ^
/home/trippels/gcc_test/usr/local/include/c++/6.0.0/tuple:598:40: note: a type with the same name but different base type is defined in another translation unit
       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
                                         ^
/home/trippels/gcc_test/usr/local/include/c++/6.0.0/tuple:102:12: note: type ‘struct _Head_base’ defined in anonymous namespace can not match type ‘struct _Head_base’
     struct _Head_base<_Idx, _Head, false>
             ^
/home/trippels/gcc_test/usr/local/include/c++/6.0.0/tuple:102:12: note: the incompatible type defined in anonymous namespace in another translation unit
     struct _Head_base<_Idx, _Head, false>
             ^
/home/trippels/gcc_test/usr/local/include/c++/6.0.0/bits/unique_ptr.h:151:41: warning: type ‘struct element_type’ violates one definition rule [-Wodr]
       typedef _Tp                       element_type;
                                          ^
/home/trippels/gcc_test/usr/local/include/c++/6.0.0/bits/unique_ptr.h:151:41: note: a different type is defined in another translation unit
       typedef _Tp                       element_type;
                                          ^
foo1.cpp:4:7: note: the first difference of corresponding definitions is field ‘i’
   int i;
        ^
foo2.cpp:4:8: note: a field with different name is defined in another translation unit
   bool a;
         ^
/home/trippels/gcc_test/usr/local/include/c++/6.0.0/tuple:598:40: warning: type ‘struct _Inherited’ violates one definition rule [-Wodr]
       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
                                         ^
/home/trippels/gcc_test/usr/local/include/c++/6.0.0/tuple:598:40: note: a type with the same name but different base type is defined in another translation unit
       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
                                         ^
/home/trippels/gcc_test/usr/local/include/c++/6.0.0/tuple:102:12: note: type ‘struct _Head_base’ defined in anonymous namespace can not match type ‘struct _Head_base’
     struct _Head_base<_Idx, _Head, false>
             ^
/home/trippels/gcc_test/usr/local/include/c++/6.0.0/tuple:102:12: note: the incompatible type defined in anonymous namespace in another translation unit
     struct _Head_base<_Idx, _Head, false>
         ^
4

2 に答える 2

6

これは GCC のバグでした (これは開発ツリーに数日間だけ存在していました)。この問題は、GCC が暗黙の typedef を非匿名と見なす別の修正によって引き起こされたため、外部構造が型マージされました (誤ってマージされました)。テストケースは現在修正されています。偽のように見える可能性のある警告についてもっと知りたいです。

于 2015-05-21T04:18:25.593 に答える
-2

クラスの 2 つの異なる定義があります。これら 2 つを一緒にコンパイルすると、これら 2 つが別々の名前空間にならなければ、直接的な競合が発生します。これが正しいのではないかと思います。

2 つの実装機能が相互に排他的であるかどうかを確認する必要があります。別々の定義を持つ 2 つの異なるソース ファイルが存在する可能性がありますが、2 つの定義を持つことが理にかなっている場合があります (つまり、Windows と Linux でスレッド API を使用しており、コンパイル設定に基づいて 2 つの異なる定義が必要です)。

于 2015-05-20T06:34:10.310 に答える