75600


現在、「ゼロからのOS自作入門」という書籍で学習している者です。  
環境はUbuntu 20.04.2、g++9.3.0で挑戦しております。

現在、筆者の用意したドライバを用いて、USBデバイスをコントロールするという章です。(購読されている方は、第6章です)  
ここで、用意されたドライバを含めたプログラムをビルドすると、以下のようなエラーが出ました。

[code]

    ./usb/xhci/trb.hpp:325:25: error: declaration of 'usb::EndpointID usb::xhci::StopEndpointCommandTRB::EndpointID() const' changes meaning of 'EndpointID' [-fpermissive]
    ./usb/endpoint.hpp:13:12: note: 'EndpointID' declared here as 'class usb::EndpointID'
    
[/code]

ソースコードの該当部分は以下の通りとなります。  
./usb/xhci/trb.hpp

[code]

    ...
    namespace usb::xhci {
    ...
      union StopEndpointCommandTRB {
      ...
        EndpointID EndpointID() const {
          return ...
        }
      };
    }
    
[/code]

./usb/endpoint.hpp

[code]

    ...
    namespace usb {
    ...
      class EndpointID {
        ...
      };
    }
    
[/code]

自分で調べた限り、どうやらclang++やVC++ではエラーにならないらしいということと、g++でも解決方法があるとのことですが、英語サイトだっため、よく理解できませんでした。一応英語サイトを見て試したことは、  
・名前空間を明らかにしたほうが良さそうなので、戻り値の型にusb::を明示する  
→ 上記とほぼ同様のエラーが出る。  
・class EndpointIDを、structに直して、戻り値の型にstructを明示する  
→ 上記と同様。  
解決法お分かりの方は、何卒ご教授いただければ幸いです。

また、私としては、単純に関数の名前をクラス型名と違うユニークなものにすればこのような問題はそもそも起こらないように思うのですが、あえてこのような実装をする場合、どのような意味があるのでしょうか？


CC BY-SA 4.0
2021-04-30T17:14:59.923
75597
2021-04-30T22:40:28.070
44216
question
c++ gcc clang
g++のコンパイルエラー：error : declaration of '~~~' changes meaning of '~~~'


> 名前空間を明らかにしたほうが良さそうなので、戻り値の型にusb::を明示する

で問題無いと思います。

[戻り値に名前空間の指定していない再現コード](https://wandbox.org/permlink/42tg7cDfNf5XZpXU)に`usb::`を追加して戻り値に名前空間の指定をすれば、[エラーは発生しません](https://wandbox.org/permlink/lgIHPrzotbo0WGOz)。

> 上記とほぼ同様のエラーが出る。

とのことですが、他に`EndpointID`と記述した箇所で`usb::`の追加(もしくは`StopEndpointCommandTRB::`の指定)が漏れているのではないでしょうか。


CC BY-SA 4.0
2021-04-30T22:40:28.070
75600
2021-04-30T22:40:28.070
9113
75597
answer