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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

5回答

1857閲覧

【C言語】構造体の中身のサイズ取得方法

hachimitu

総合スコア36

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2019/07/30 11:25

#やりたいこと
構造体自体のサイズを取得することはできるのですが、下記の様な構造体の中身(例えば payload_data1)のサイズをdefineで持っておきたい

C

1typedef struct MST_TO_PC_DATA_FRAME_handle_typedef 2{ 3 uint8_t slv_id; 4 uint8_t slv_error_status; 5 uint8_t command_id; 6 int32_t payload_data1; 7 int32_t payload_data2; 8 int32_t payload_data3; 9 int32_t payload_data4; 10}__PACKED MST_TO_PC_DATA_FRAME_handle_typedef; 11#define MST_TO_PC_DATA_FRAME_handle_typedef_size sizeof(MST_TO_PC_DATA_FRAME_handle_typedef)

#質問
構造体の中身ひとつひとつのサイズを#defineで事前に取得するにはどうしたらよろしいでしょうか。
お手数をおかけしますが宜しくお願い致します。

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

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

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

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

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

cateye

2019/07/30 11:38

>ひとつひとつのサイズ・・・これはint32_t(ほかも同様)ならその大きさ(バイト数)ということですか?
hachimitu

2019/07/30 11:43

その通りでございます!
guest

回答5

0

皆さん、難しく考えすぎでは?

int32_t payload_data2; int32_t payload_data3;

int32_t などは <stdint.h> に定義があるんだから、これで十分だと思います。

#include <stdint.h> #define PAYLOAD_DATA1_SIZE sizeof(int32_t) #define PAYLOAD_DATA2_SIZE sizeof(int32_t)

投稿2019/07/31 05:44

rubato6809

総合スコア1380

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

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

Zuishin

2019/07/31 06:43

payload_data2 が int32_t でなくなったときに困るのでは?
rubato6809

2019/07/31 09:01

そうか、構造体の定義が変更されるまでの命だったかー
hachimitu

2019/07/31 11:11

そうなんですよ。payload_dataのサイズが変更されても、問題ないようにしたいの今回の狙いなのです。
Zuishin

2019/10/16 08:57

ということで低評価します。
guest

0

ベストアンサー

C

1#define MST_TO_PC_DATA_FRAME_handle_typedef_size \ 2 sizeof( ((__PACKED_MST_TO_PC_DATA_FRAME_handle_typedef*)0)->slv_id)`

とか。 (typedefで付けた型名が__PACKED_MST_<以下略>だとして)

一瞬0へのアクセスに見えるかも知れないけど、sizeofはコンパイル時に解決されて変数アクセスは実際には行われません。

投稿2019/07/30 12:25

thkana

総合スコア7639

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

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

pepperleaf

2019/07/30 15:07

define の前に typedefが必要と言う問題が、、。 かなり、ややこしくなります。 定義する順番とかで、注意が必要で、自分としてはやりたくない。
hachimitu

2019/07/31 00:19

ありがとうございます。試してみます! ちなみに (__PACKED_MST_TO_PC_DATA_FRAME_handle_typedef*)0 ↑はどういう意味をもつのでしょうか。
thkana

2019/07/31 04:53

__PACKEDは質問の間違いということで。 (MST_TO_PC_DATA_FRAME_handle_typedef*)0 は、0をMST_TO_PC_DATA_FRAME_handle_typedef型へのポインタにキャストしています。つまり、0番地からMST_<略>型のデータがある..."つもり"になります。そして、MST_<略>型のメンバのslv_idとかpayload_data1とかが"あるとしたら"そのサイズはいくつか、というのをsizeofで求めています。
thkana

2019/07/31 05:01

pepperleafさん #defineとtypedefは前後関係ないですよ。 ソースコード中で MST_TO_PC_DATA_FRAME_handle_typedef_size が出てきたらsizeof( MST_<略>)に置き換えるだけですから。もちろん、ソースのその時点でtypedefが有効でなきゃいけない、というのはありますが。
hachimitu

2019/07/31 11:10

0をポインタにキャストってあまりイメージつかないですけど、そんなことできるんですね。参考になります。そして私のやりたいこともできました!ありがとうございます!
pepperleaf

2019/07/31 11:58

> #defineとtypedefは前後関係ないですよ。 C言語の場合、参照する前に定義が必要。 ただ、今回の場合、struct と #defineの組合せてなんで、深く考える必要無かった。
thkana

2019/07/31 12:36

#defineはあくまでプリプロセッサでの文字置換の指示でしかないので、マクロ定義の時点でその中に登場するのが定義済みのシンボルかどうかなんて深くどころか全く考える必要はないです。
pepperleaf

2019/08/03 03:54

> マクロ定義の時点でその中に登場するのが定義済みのシンボルかどうかなんて 今更ですが、言われる通り。マクロはプリプロセッサで展開でした。structの評価はその後。(さすがにここは違わないか)
guest

0

sizeof(__PACKED MST_TO_PC_DATA_FRAME_handle_typedef.payload_data1)


コンパイルエラーになるので修正
sizeof(((MST_TO_PC_DATA_FRAME_handle_typedef*)0)->payload_data1)
だった。。

# offsetofマクロというのがあってだな

投稿2019/07/30 11:52

編集2019/07/30 12:38
y_waiwai

総合スコア87774

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

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

cateye

2019/07/30 12:08

無知で申し訳ないのですが、__PACKEDは必要なのですか?
guest

0

stdint.hとlimits.hを参考にして下さい。・・・大抵は定義されています。

[蛇足]
個別のサイズを定義してどうするのか?・・が、ちょっと気になったのですが、構造体のパディング(詰物)が知りたいならコンパイラ(gcc,clang)の"-Wpadded"コンパイルオプションを付ければ、パディングのサイズも教えてくれます。・・・私は、-Wno-paddedで文句言われないようにしてるけど・・・うるさいし^^;

投稿2019/07/30 11:50

編集2019/07/31 06:40
cateye

総合スコア6851

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

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

cateye

2019/07/30 12:06

stdint.hにない型ならy_waiwaiさんの方法でしょうか?
cateye

2019/07/31 06:56 編集

Wpaddedについては、clangのみ検証済み。gccは警告メッセージだけみたい? clang →warning: padding struct 'struct MST_TO_PC_DATA_FRAME_handle_typedef' with 1 byte to align 'payload_data1' [-Wpadded]
guest

0

c

1#define ... sizeof(MST_TO_PC_DATA_FRAME_handle_typedef::payload_data1)

こういうことですか?

投稿2019/07/30 11:48

yuki23

総合スコア1448

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

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

cateye

2019/07/30 12:01

スコープ解決演算子(::)はc++です。Cでは使えません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問