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

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

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

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

Q&A

解決済

4回答

10777閲覧

構造体の前方宣言が効かない

退会済みユーザー

退会済みユーザー

総合スコア0

C++

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

0グッド

0クリップ

投稿2020/10/24 01:49

下記の提示コードですがなぜ未定義のstruct testというエラーが出るのでしょうか?前方宣言によって既に定義されていると思うのですが構造体の前方宣言は出来ない。のでしょうか?

参考サイト: https://marycore.jp/prog/c-lang/declare-struct/#:~:text=%E5%88%A9%E7%82%B9%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82-,%E6%A7%8B%E9%80%A0%E4%BD%93%E3%81%AE%E5%89%8D%E6%96%B9%E5%AE%A3%E8%A8%80,%E8%A1%8C%E3%81%86%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82&text=%E5%AE%9A%E7%BE%A9%E3%81%8C%E8%A1%8C%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84,%E3%81%AA%E3%81%84%E3%81%A8%E3%81%84%E3%81%86%E5%88%B6%E9%99%90%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82

cpp

1#include <iostream> 2#include <array> 3 4 5#include <random> 6#include <time.h> 7 8#include "glm/ext.hpp" 9#include <vector> 10 11struct test; 12 13struct test g() 14{ 15 struct test b = test(); 16 17 return b; 18} 19 20struct test; 21struct test 22{ 23 int a; 24}; 25 26 27int main() 28{ 29 struct test a = g(); 30 31 return 0; 32} 33

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

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

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

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

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

guest

回答4

0

前方宣言によって既に定義されていると思うのですが

宣言と定義は区別して下さい。

こういう名前の構造体があるよ、というだけが宣言。その内容はこうなっています、というのが定義。宣言だけでは内容を教えられていないので、コンパイラは内容を扱うプログラムを解釈出来ません。
struct test;
でtestという構造体があるぞ、という事しか知らなければ、
struct test b = test();
で実際に何をすればいいのか、コンパイラにはわからないのです。

C++

1struct test 2{ 3 int a; 4};

という情報が与えられてから初めて
struct test b = test();
で何をすればいいのかがわかるのです。

C/C++の文法は原始的なので、ソースファイル単位で「その場所までに教えられていること」だけでプログラムを構成しなければいけません。実に単純な規則とも言えます。

投稿2020/10/25 14:30

thkana

総合スコア7659

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

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

thkana

2020/10/25 15:09

あ、 class A{ void a(){ b(); } void b(){ return ; } }; は通っちゃうか。 まぁ、原則としてそういうことで、と思っておけばそんなに外さないかと。
guest

0

自分で提示したリンクを読むとわかると思いますが、

定義が行われていない段階での宣言は前方宣言と呼ばれます。前方宣言された型は不完全型となるため、実際の定義が行われるまでは、メンバ変数への参照が行えなかったり、仮引数型としての宣言が行えないという制限があります。ただし、ポインタ変数としての宣言は可能です。

【C言語】構造体の定義/宣言/初期化【struct 完全解説・豆知識】 | MaryCore

投稿2020/10/24 02:09

Daregada

総合スコア11990

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

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

0

ベストアンサー

まず、参考にされているサイトはCについてです。C++については異なることがありますので、注意が必要です。C++について知りたいのであれば、C++についてだとはっきり書かれたサイトのみを参考にすることをお勧めします。(CとC++は似ていますが、混同してはいけません)

C++においてstructclassの違いはデフォルトのアクセス指定子のみで、どちらもクラスです。C++では構造体とクラスは区別されません。これまでstruct test;と宣言しか書いていない場合は、testクラスは不完全クラス型になります。そのような不完全クラス型は関数定義の引数の型や戻り値の型に使用できません。

関数定義 | 関数宣言 - cppreference.com

関数の引数の型および戻り値の型は、[削除された関数を除き (C++11以上)]不完全クラス型にできません。 完全性のチェックは関数の__本体__の文脈で行われます。 これは、たとえ定義の時点で不完全であっても (関数の本体内では完全です)、メンバ関数がそれらの定義されているクラス (または囲っているクラス) を返すことを許容します。

これは関数定義時の制限で関数宣言では不完全クラス型であっても使用できます。また、クラス定義内での場合は、完全とみなされるようです。完全クラス型にするには、クラス定義を書いておく必要があります。

投稿2020/10/24 02:44

raccy

総合スコア21735

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

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

退会済みユーザー

退会済みユーザー

2020/10/25 14:08

つまりどうすればコンパイルエラーを抜けれるのでしょうか?
kazuma-s

2020/10/27 14:45

struct test { int a; }; を struct test g() より前に書く。
guest

0

構造体の前方宣言は出来ない。のでしょうか?

できますが、それで処理可能なのは宣言だけで済む箇所(構造体へのポインタの宣言など)だけです。

構造体型の引数や返り値、変数定義を使うには、構造体の定義が必要ですので、前方宣言では足りません。

投稿2020/10/24 01:57

maisumakun

総合スコア145208

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問