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

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

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

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

Q&A

解決済

2回答

488閲覧

【ある試験問題の解答の相談】int型の型変換について

crmy

総合スコア15

C

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

1グッド

0クリップ

投稿2024/08/15 21:39

C言語・情報学の初学者です。
とあるC言語の試験問題について、理解できない部分があり質問させていただきます。

【試験問題内容】
単体テストにて以下の不具合が発生した。原因を修正し、プログラムを修正せよ。
なお単体テストの結果は、32ビットOSの汎用PC上で実施された。

不具合の対象関数:func
不具合の内容:subfuncの戻り値判定「if(s2_ret == RET_NG)」で必ずFALSEになる。

typedef short s2 ;

#define RET_OK 0x0000
#define RET_NG 0xFFFF

s2 func(void)
{

s2 s2_ret;

s2_ret = subfunc (xx, yy); /subfuncは戻り値としてRET_NGを返す/
if (s2_ret == RET_NG)
{
com_internal_err ();
}
以下略

【解答】
s2_retはS2型、RET_NGは直値(0xFFFF)であるため、型が一致しない。
そのため、int型に型変換して比較され、(-1)と65535の比較になり、FALSEになる。

【疑問】
上記回答の「int型に型変換して比較され、(-1)と65535の比較になり」という部分がわかりません。
特に-1という値がどこから出てきたのかがわかりません。

ご回答よろしくお願いします。

tatsu99👍を押しています

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

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

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

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

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

otn

2024/08/16 10:26

> RET_NGは直値(0xFFFF)であるため、 「直値」という言葉は、自分では使ったことないですが、検索すると割と使われているようですね。Wikipedia「リテラル」にも載ってる。 「リテラル」のことのようですが、全く同じなのか?少し意味が違うのか? この言葉を使う人は、「関数リテラル」のことも「関数直値」というのかとか、「式が埋め込まれた文字列リテラル」も「直値」と呼ぶのかとか、気になります。
guest

回答2

0

ベストアンサー

これは C の言語仕様に照らすと設問も解答も間違っている……というと言い過ぎかもしれませんが少なくとも説明が不十分だと思います。

関数 subfunc の返却値を s2_ret に代入するにあたって short に変換する暗黙の型変換が入っています。

単に short と書いた場合は signed short int のことです。 この型は一般的には 16 ビットの大きさを持ち、負数の表現がある分だけ表せる絶対値は unsigned short int より小さいです。 signed short int0xFFFF を表現することが不可能であるということです。

変換後の型が符号付き整数型、かつ変換後の型の表現範囲で変換前の値を表せないときの結果は言語仕様では「処理系定義の値となるか、又は処理系定義のシグナルを生成するかのいずれか」とされていてどういう値になるのか言語仕様では決めていません。

2の補数形式と考えてそのビットパターンを読み替えると -1 になるようなアーキテクチャが多いのは確かですし、それも正しい挙動のひとつですが言語仕様でそう決まっていないのを -1 という値で決め打ちして書いているのは説明不足です。


リテラルにも型があり、 0xFFFF の型は unsigned int です。

== (を含む二項演算子のいくつか) は比較前に型を揃えるというルールがあり、詳細は面倒な場合分けで規定されているのでここでは述べませんが unsigned intsigned short int を比較するときは両端を int に型変換するというルールです。

なので比較するときには int になっていることは確かですが前述の通り代入の段階で値がおかしくなっていることが直接の原因なのでそのことが説明されていないのが悪い解答だと思います。

余談ですが型が一致するときでも両端が int より小さい型の場合は両端ともに int に拡張される (整数拡張; integral promotion) というルールもあるので型が異なるから型変換されるというわけでもありません。

投稿2024/08/16 01:52

SaitoAtsushi

総合スコア5571

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

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

退会済みユーザー

退会済みユーザー

2024/08/16 07:34

一応「32ビットOSの汎用PC上」なのでx86系の想定は大丈夫かもしれません。処理系依存とはいえ、わざわざx86系で「2の補数形式と考えてそのビットパターンを読み替えると -1 」にならない実装にすることもないでしょう。流石に重箱の隅かもしれません。まあ個人的にはどっちでもいいんですが、多分これも言わないと不公平な気がしたので…。
matukeso

2024/08/16 13:48

>リテラルにも型があり、 0xFFFF の型は unsigned int です intですよね。 まさかintが16bitの処理系を考えてたりとか?(32ビットOSであることとintが32bitであることは必ずしもイコールではないのでたとえば、Win16アプリを32bit Win7で動かす例みたいなのを強弁できなくもないけど)
SaitoAtsushi

2024/08/16 18:37

ああ、これはシンプルに書き間違いです……
guest

0

特に-1という値がどこから出てきたのか

short (16 bit?) の 0xffff が -1 ということでは。

投稿2024/08/15 21:48

編集2024/08/15 21:50
jimbe

総合スコア13068

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

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

crmy

2024/08/16 08:50

ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.40%

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

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

質問する

関連した質問