質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

3回答

2626閲覧

ヘッダーファイルで構造体を返り値に持つ関数の宣言ができない

vivi1

総合スコア1

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2021/05/16 12:42

編集2021/05/16 14:32

前提・実現したいこと

VC++で構造体を使ったプログラムを書いています。
構造体を定義したヘッダーファイルをインクルードした、別のヘッダーファイルからその構造体を返り値に持つ関数の宣言をするとビルドエラーが出てしまいます。
ソースファイルから構造体を定義したヘッダーファイルをインクルードして、構造体を返り値に持つ関数を定義したところ、エラーもなくビルドができました。

発生している問題・エラーメッセージ

重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態 エラー C2461 'msg': コンストラクターに、仮引数が指定されていません。 msg.h エラー C4430 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません。 r_msg.h エラー C2146 構文エラー: ';' が、識別子 'retMsg2' の前に必要です。 r_msg.h エラー C2461 'msg': コンストラクターに、仮引数が指定されていません。 msg.h エラー C4430 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません。 r_msg.h エラー C2146 構文エラー: ';' が、識別子 'retMsg2' の前に必要です。 r_msg.h エラー C2461 'msg': コンストラクターに、仮引数が指定されていません。 msg.h

該当のソースコード

c++

1/** main.cpp **/ 2#include "msg.h" 3 4int main() { 5 6 return 0; 7}

header

1#pragma once 2/** msg.h **/ 3#ifndef _MSG_ 4#define _MSG_ 5#include <string> 6#include "r_msg.h" 7using namespace std; 8 9struct msg { 10 string msg = ""; 11}; 12#endif

header

1#pragma once 2/** r_msg.h **/ 3 4#include "msg.h" 5msg retMsg2();

c++

1/** r_msg.cpp **/ 2#include "r_msg.h" 3 4msg retMsg2() { 5 msg Msg; 6 return Msg; 7}

試したこと

  • ソースファイルから構造体を呼び出してもエラーは発生しませんでした。
  • 関数の宣言から、変数の宣言に書き換えてみましたが、同じエラーが発生しました。

補足情報(FW/ツールのバージョンなど)

visual studio 2019
c++ 14
windows 10 Home 64bit

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thkana

2021/05/16 12:59

/** msg.h **/ #include "r_msg.h" extern struct msg { string msg = ""; }; /** r_msg.h **/ #include "msg.h" msg retMsg2();//エラーが発生する 相互にインクルードしあって、たぶんこれはエラーになると思うのですが?
vivi1

2021/05/16 13:03

msg retMsg2(); の宣言や定義を削除すると正常に動くので、相互インクルードにはなっていないと勝手に判断していたのですが、やはり相互インクルードしてしまっているのでしょうか?
thkana

2021/05/16 13:11

だって、msg.hの冒頭で #include "r_msg.h" r_msg.hの冒頭で #include "msg.h" これが相互インクルードでなければなんなのでしょう?
vivi1

2021/05/16 13:20

ありがとうございます。 たしかに、エラーは発生していませんが、相互インクルードに違いはないと思い、インクルードガードを追加しておきました。
thkana

2021/05/16 13:28

そもそもmsg.hでr_msg.hをインクルードしなきゃいけない理由がないのであって、 msg.hでr_msg.hをインクルードしているのがおかしいのですが。 でも、相互インクルードしてエラーが出ないといしたらそれもおかしい... msg.h中にわざとエラーを埋め込んだら(例えば#errorで)、ビルド時にちゃんとそのエラーは出ますか?
thkana

2021/05/16 13:37

> インクルードガードを追加しておきました それ、なにか変じゃありませんか?
vivi1

2021/05/16 13:40

msg.h内に#errorを記述したところビルドエラーが発生しました。 msg.hでr_msg.hをインクルードするのはmsg.hからr_msg.hの関数にアクセスしたいためです。
thkana

2021/05/16 13:45

> msg.hからr_msg.hの関数にアクセスしたいためです。 「したい」というあなたの意思は知りませんが、事実として struct msg { string msg = ""; }; はr_msg.hにかかれた内容に一切依存していませんよね?
thkana

2021/05/16 13:56

質問に書いてあるファイル4つで(VisualStudioのIDEなら新たにプロジェクトを作成して)、質問にあるエラーが再現するか再度確認してみてください。そのへんから話がおかしくなっている気がします。
vivi1

2021/05/16 13:57

すみません、質問に関係ないと思い省いてしまっていますが、msg.cppからr_msg.cppの関数にアクセスしています。 そのため、msg.hまたはmsg.cppにインクルードを記述しなければならず、msg.hにインクルードを記述しています。 なので、インクルードをしています。 >> インクルードガードを追加しておきました >それ、なにか変じゃありませんか? インクルードガードを全文に変更すると、r_msg.hから見るとmsg構造体自体が定義されていないことになってしまうので、こうしています。
thkana

2021/05/16 13:59

> r_msg.hから見るとmsg構造体自体が定義されていないことになってしまうので、こうしています。 だから、それって変だ、と。
thkana

2021/05/16 14:01

> msg.cppからr_msg.cppの関数にアクセスしています。 > そのため、msg.hまたはmsg.cppにインクルードを記述しなければならず そこでmsg.hにインクルードを記述するのは適切じゃないでしょう。
vivi1

2021/05/16 14:16

>> r_msg.hから見るとmsg構造体自体が定義されていないことになってしまうので、こうしています。 >だから、それって変だ、と。 main.cppから一度、msg.hをインクルードするので、その後r_msg.hからインクルードしてもインクルードガードによってmsg構造体が見えなくなっています。 通常はmain.cppでインクルードしているのでr_msg.hからもアクセスできると思うのですが、私の環境では、msg認識子が見つかりません。 >そのへんから話がおかしくなっている気がします。 一度、VisualStudioから新たにプロジェクトを作成して、このソースを実行してみましたが、同様のエラーが出ています。
guest

回答3

0

msg.h の #include "r_msg.h" によって、struct msg より先に retMsg2()の宣言が来る状態になっています。msg.h の #include "r_msg.h" を削除してください。

msg.hでr_msg.hをインクルードするのはmsg.hからr_msg.hの関数にアクセスしたいためです。

その依存もおかしいので、そのあたりの事情も開示すべきでしょう。

投稿2021/05/16 13:53

int32_t

総合スコア21695

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

vivi1

2021/05/16 14:11

プログラム全体の構造としては、 - main.cpp - msg.cpp/msg.h - r_msg.cpp/r_msg.h -その他、msgに関連したソース となっていて、main.cppの関数からmsg.cppの関数を呼び出し、msg.cppの関数からr_msg.cppの関数やその他のソースファイル内の関数を呼び出しています。 その他のソースはmsgをインクルードせずとも動き、しかし、msgから実行したいのでmsgでインクルードしています。 現状ではr_msgのみ、msg.hのmsg構造体を利用するため、このようなソースとなっていますが、今後msg構造体は別のヘッダーでも利用する予定なので、msg.hにある状態が好ましいです。
int32_t

2021/05/16 14:18

> msg.cppの関数からr_msg.cppの関数やその他のソースファイル内の関数を呼び出して であれば、#include "r_msg.h" は msg.h ではなく msg.cpp 内にあるべきです。
vivi1

2021/05/16 14:21

msg.cppに記述すると、「複数回定義されているシンボルが見つかりました」と出てきます msg.hは全文にインクルードガードしています。
int32_t

2021/05/16 14:23

> 「複数回定義されているシンボルが見つかりました」 詳細を質問文に追記してください。 とにかく、#include "r_msg.h" を msg.h に置くという方向での解決はあり得ないのです。
vivi1

2021/05/16 14:34

アドバイス、ありがとうございます。質問文に追記しました。 問題切り分けのために、質問に記述してある最小構成で実行したところ、エラーの文が別の文に変わったので、そちらのエラーを載せておきました。 ご教授のほど、よろしくおねがいします。
int32_t

2021/05/16 14:42

これは、型名と同名のデータメンバはダメということなので、どちらかリネームしてください。
thkana

2021/05/16 14:46

おいおい... > エラーの文が別の文に変わったので、そちらのエラーを載せておきました。 それって「もとの現象を再現していないばかりでなく、場当たり的対応で別の問題を発生させた」ということでは? 確実に「もとのソースで起こっている現象(エラー)を再現する最小構成」を作ってください。それとは違うものを検討するのは(あなたのデバッグ練習にはなるかも知れませんが)質問の解決には寄与しません。つぎつぎと新しいエラーを作り出しては解決するのには付き合えません。ちゃんと元の状況を再現したコードが提示されるまで私は黙ります。
vivi1

2021/05/16 15:08 編集

>それって「もとの現象を再現していないばかりでなく、場当たり的対応で別の問題を発生させた」ということでは? 誤解を招くような表現をしてしまい、申し訳ありません。 元のソースでは、複数のインクルードをしているため、インクルードをするファイルを変えると、それに付随し、多数のインクルードがループしてしまいます。 それに気が付かずにエラーとして質問してしまいました。ですが、この問題は自分の手で解決できるもので、また今回の質問には全く関係のないものなので、このような表現をさせていただきました。 また、エラーが起きている部分では現状これ以上の処理を記述しておらず、その他の処理は、エラーに全く関係ないか、インクルードの記述となっており、この構成がエラーを再現する最小構成です。
vivi1

2021/05/16 15:08 編集

>これは、型名と同名のデータメンバはダメということなので、どちらかリネームしてください。 構造体名をリネームしたところ「コンストラクターに...」というエラーは消えましたが、まだ「型指定子が...」と「構文エラー」が消えません。 これは、構造体を認識していないということなのでしょうか? どうすれば解決できるのでしょうか? 質問ばかりになってしまい申し訳ありません。
int32_t

2021/05/16 15:24

構造体をリネームしたのなら、r_msg.h 内のmsgもそれに合わせてくだざい。もしそれも実施済みなら、現状のそーすすべてを質問に追記してください。
thkana

2021/05/16 22:02

> この構成がエラーを再現する最小構成です。 であるなら、 > msg.cppからr_msg.cppの関数にアクセスしています。 という条件は消えます。だって、msg.cppは存在しませんから。いいんですね?
guest

0

私のてもとでは、

C++

1// msg.h 2#pragma once 3#include <string> 4struct msg { //型定義にexternは付かない 5 std::string msgs= ""; //MS-C++はmsgとするとコンストラクタと誤解する? 6};

C++

1//r_msg.h 2#pragma once 3#include "msg.h" 4msg retMsg2();

C++

1#include "r_msg.h" 2 3msg retMsg2(){ 4 msg Msg; 5 return Msg; 6} 7 8int main(){ 9 retMsg2(); 10}

でエラーは出ません。あなたのしていることとどこが違うのでしょう?

投稿2021/05/16 13:38

thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

vivi1

2021/05/16 13:45

質問のため簡略化していますが、本来は main.cppの関数からmsg.cppの関数を呼び出し msg.cppの関数からr_msg.cppの関数を呼び出しています。 また、msg.hのstruct msgは他のソースファイルでも利用するため、msg.hから動かすことは控えたいです。
guest

0

r_msg.hでは、struct msgは定義されてませんよ

なので、

C++

1/** r_msg.cpp **/ 2#include "r_msg.h" 3 4msg retMsg2(){ 5 msg Msg; 6 return Msg; 7}

これでは定義されてないと怒られるのは当然ですね

投稿2021/05/16 12:46

編集2021/05/16 13:11
y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

vivi1

2021/05/16 12:49

すみません、質問用に実行しているソースコードとは別のソースコードを記述していたのですが、r_msg.hに#include "msg.h"を追加するのを忘れていました。 修正しておきます。 回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問