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

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

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

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

Q&A

解決済

1回答

3039閲覧

C++ sizeof(int)とは何なのでしょうか。

yamatail

総合スコア77

C++

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

0グッド

0クリップ

投稿2022/01/07 02:28

今考えているのは、

① 別PCからソケットでコマンドを送信
変数 : Length, command

② 本サーバーが
変数 : Length, command
を受けて、以下のC++を実行

③ C++は、制御機器にソケットでコマンドを送信して、データを受信する。
ソースは、下に載せます。

いま問題になっているのが③の制御機器にコマンドを送信する部分です。
main()command(length, com) // 一番下の行
の部分で、返りの長さが決まっているコマンドに関しては、
変数 : 7(=Length), -get version(=command)を受信して
command(7, "-get version")
とすれば問題なく帰ってくるのですが、
lengthのところにsizeof(int)が入っているコマンド(実際に動くサンプルが手元にありそれを元に作りかえております)があり、
これの理解が出来ていなくて困っております。

sizeof(int)が、int型のメモリサイズを返すものというのは調べれば出てくるのですが、
わたしのプログラムの場合、どういう事になっているのかが分かりません。
例)command(sizeof(int), "-reset")

コマンドごとに決まっているので、
変数 : -1(=Length), -reset(=command)
if (Length = -1) length = sizeof(int);
を付け足して、場合分けをすれば上手くいくのかなとも思うのですが
私の知識不足でどういう意味か分からず完成させるのもと思い
詳しい方がいらっしゃいましたらお教えいただきたいと思い、質問させていただきました。

必要な情報のご指摘があれば、更新させていただきます。
どうぞよろしくお願いいたします。

C++

1 2// グローバル変数 3const int socketBufferSize = 6*1280*sizeof(int); 4char socketBuffer[socketBufferSize]; 5 6// コマンド送信 7bool send(const char *message, va_list args) 8{ 9 memset(socketBuffer, 0, socketBufferSize); // バッファのクリア 10 vsprintf(socketBuffer, message, args); // コマンドをバッファに出力 11 12 int n; 13 if (!tcp) n = sendto(sockfd, socketBuffer, strlen(socketBuffer), 0, (struct sockaddr*) &serverName, sizeof (serverName)); 14 else n = send(sockfd, socketBuffer, strlen(socketBuffer), 0); 15 16 if (debug) printf("%i bytes sent: %s\n", n, socketBuffer); 17 if (n < 0) 18 { 19 printf("Error: Could not send command\n"); 20 return false; 21 } 22 return true; 23} 24 25// 応答を受信してバッファに保存 26bool receive(int length) 27{ 28 if (length > socketBufferSize) 29 { 30 printf("Error: Socket buffer too small\n"); 31 return false; 32 } 33 34 struct sockaddr_in addrRemote; 35 unsigned int cbAddr = sizeof(addrRemote); 36 37 memset(socketBuffer, 0, socketBufferSize); // バッファのクリア 38 int responseLength = 0, n, readMax; 39 40 while (true) // 読み取り(応答の長さが読み取られるまで)、応答が複数のパケットに分けられる可能性あり 41 { 42 readMax = length - responseLength; // 読み取る残りのサイズ 43 44 if (!tcp) n = recvfrom(sockfd, socketBuffer + responseLength, readMax, 0, (struct sockaddr *) &addrRemote, &cbAddr); 45 else n = recv(sockfd, socketBuffer + responseLength, readMax, 0); 46 47 if (n <= 0) 48 { 49 printf("Error: Could not receive response\n"); 50 return false; 51 } 52 53 responseLength += n; 54 if (responseLength == 4 /*Server returned error code*/ || responseLength == length) break; 55 } 56 57 if (responseLength == 4 && getInteger(0) < 0) 58 { 59 printf(">>>> Error: Received error code %i\n", getInteger(0)); 60 return false; 61 } 62 63 if (debug) printf("%i bytes received\n", responseLength); 64 return true; 65} 66 67bool command(int recvLength, const char *command, ...) // recvLength: 応答のサイズ 68{ 69 bool result; 70 71 va_list args; 72 va_start(args, command); 73 result = send(command, args); 74 if (result) result = receive(recvLength); 75 va_end(args); 76 77 return result; 78} 79 80int main(int argc, char** argv) 81{ 82 83 for (int i = 0; i < argc; i++) 84 { 85 if (!strcmp(argv[i], "-debug")) debug = true; 86 if (!strcmp(argv[i], "-host")) sprintf(host, argv[++i]); 87 if (!strcmp(argv[i], "-port")) port = atoi(argv[++i]); 88 if (!strcmp(argv[i], "-udp")) tcp = false; 89 } 90 91 // socket通信の設定 92 if (!init()) return -1; 93 94 // 機器にコマンド送信 95 length = argv[1]; 96 com = argv[2]; 97 command(length, com); 98 printf("version %s\n", socketBuffer); 99} 100

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

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

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

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

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

fana

2022/01/07 02:37

> sizeof(int)が、int型のメモリサイズを返すものというのは調べれば出てくるのですが、 > わたしのプログラムの場合、どういう事になっているのかが分かりません。 何がわからない事柄なのでしょうか? 「sizeof(int)とは何か?」に関しては調べて出てきたということなら現在の疑問点は一体何になるのでしょう?
itagagaki

2022/01/07 02:45

サーバーが返すデータ長(つまり受け取るべきデータ長)を指定するのに、受け取る側のマシンに依存するsizeof(int)を指定するのはおかしいのではないか?と私は思いましたが、質問はそういうことですか?
ozwk

2022/01/07 02:55

状況がよくわかりません コマンド表みたいなドキュメントがあって、その中にsizeof(int)と書かれているんでしょうかね?
fana

2022/01/07 03:03

ああ, 「ある条件下でしかまともに動かないような記述がわざわざされているんだけどコレ何なの? コマンド仕様で定められている値をそのまま書かないことに何か理由があるの?」 っていうような話か. であれば,コマンド仕様で定められている値をそのまま書く形にしちゃえば良いのでは.
yamatail

2022/01/07 03:20

皆様、分かりにくい書き方で大変申し訳ありません。。。 この機器のコマンドリストは存在します。そして、その表に[Return Type, Return Size]が記述されてあります。例に挙げました"-reset"の場合は、返り値の欄は空白で、"-get version"の場合は、[char, 7]です。返り値の期待できない(reset やsetコマンドなど)コマンドの場合にreceive関数の引数が"sizeof(int)"になっているようです。このsizeof(int)をreceiveの長さに指定することはよくあることなのでしょうか。
itagagaki

2022/01/07 03:32

「返り値の期待できない(reset やsetコマンドなど)コマンド」ではサーバーは何もデータを送って来ないということですか? それなら、その場合はreceiveを呼んではいけないのでは。 result = send(command, args); if (result) result = receive(recvLength); となっているので、その場合は result が false になるのでしょうか? それなら recvLength 自体使われることがないので、値は何だっていいのでは。 何だっていいからと言って sizeof(int) にしておく合理的な理由は無いと思いますが。 その場合サーバーがintの値を返すのなら…という回答がありますが、sizeof(int) はマシンに依存するもので、サーバーの返すデータ長と一致するとは限らないので、それはおかしいと思います。
fana

2022/01/07 03:50

そのコマンドリストにおいて > 返り値の欄は空白 の場合には,実際どういう仕様となっているのか?…なんてことは,誰にとっても謎だから,問うてても仕方ないような. その仕様を知る者(そのコードの出所とか使ってた人とか)に問うしかないだろうし,それが不可能なら実動作から確認していくしかないんじゃない?
yamatail

2022/01/07 03:58 編集

"-reset"コマンドですが、コマンドリストでは、空白ですが、debugモードで if (debug) printf("%i bytes received\n", responseLength); を確認したところ "4 bytes received"との出力がされました。 ただしエラーなどは、なさそうです。
fana

2022/01/07 04:08 編集

じゃあ,よくわからんけども,「何かしら4byteの応答が来る」っていう仕様なんじゃない? 仮にそういう仕様なのであって, 且つ,そのコードを実際に使っていた(使っている)環境では sizeof(int) の値が 4 なのであれば,辻褄が合っている. それだけのこと. 例えば【sizeof(int)が4となるその環境でしかそもそも使わないプログラムだという想定】があった上で実装された(その場限りのプログラムとか)ならば,(「intのサイズ」という意味合いで)"4" を "sizeof(int)" って書くことは間違いというわけではない…と思う. (あえてそう書く必要とか正当な理由があるのか? っていうと「ないな」と思うけども.「意味的にintな応答のサイズ」みたいな定数なりdefineなりを使えばいいのに.)
yamatail

2022/01/07 04:33

コメントありがとうございます。 動作をさせながら、確認してみます。 皆様のご意見大変参考になりました。m(_ _)m
guest

回答1

0

ベストアンサー

質問の意図をつかみ損ねているかもしれませんが、その例 command(sizeof(int), "-reset") だと "-reset" コマンドを送信した時、その返答が int で返されるので、int サイズ分をレシーブするようcommand 関数に指定しているということだと思います
ちょっと質問文でお話されていることと、提示されたソースコードのどことどこが対応しているのか分かりづらいので、その辺りを編集されると良いかも知れません

投稿2022/01/07 02:48

WoodenHamlet

総合スコア306

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

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

yamatail

2022/01/07 03:31

ご返事ありがとうございます。 質問への追記にも書いたのですが、コマンドリストには、"-reset"の返り値は、空白になっております。そういう場合にrecevice関数の長さに"sizeof(int)"を指定することは、よくある?おかしい?ことなのでしょうか。そもそもsizeof(int)を指定するのは、int型1つのときのメモリサイズと考えていいのでしょうか。というあたりが質問、疑問点でした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問