C言語なら俺に聞け 163

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん (ワッチョイ 7bba-Lem2)
垢版 |
2024/07/16(火) 22:43:54.18ID:ZrsCjURC0
!extend:checked:vvvvv:1000:512
(新スレ立ての際上記コマンドを2行書き込んでください)
C言語の話題のみ取り扱います C++の話題はC++スレへ
質問には最低限の情報(ソース/コンパイラ/OS)を付ける
数行で収まらないソースは以下を適当に使ってURLを晒す
https://paiza.io/
https://ideone.com/
http://codepad.org/

C17
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf

C11
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf

C23 最新ドラフト
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3047.pdf

C99
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
http://kikakurui.com/x3/X3010-2003-01.html

C FAQ 日本語訳
http://www.kouno.jp/home/c_faq/

JPCERT C コーディングスタンダード
https://www.jpcert.or.jp/sc-rules/

※前スレ
C言語なら俺に聞け 162
https://mevius.5ch.net/test/read.cgi/tech/1698653580/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
273デフォルトの名無しさん (ワッチョイ 63e3-VZV9)
垢版 |
2024/09/26(木) 23:55:11.03ID:jCy2QsTx0
>>235
これの1行目は文字列長によらず固定値にならない?
char* と char[] を区別できてないように思う

// これは (ヌル文字を含む) 4バイトのデータがスタック上に作られる
// sizeof(a1) の結果は文字列数により変わる
char a1[] = "abc";

// こう書いた場合、文字列の実体は静的な領域 (テキスト領域) に確保され、
// a2にはそのアドレスが渡される。
// sizeof(a2) はポインタのサイズであり、値は文字列長によらず固定
char* a2 = "abc";
274デフォルトの名無しさん (ワッチョイ 63e3-VZV9)
垢版 |
2024/09/27(金) 00:02:43.63ID:ju4/Ooeg0
char* でも char[] でも、a[n] と書けばn文字目を参照するのは変わらない
これはポインタの [] 演算子は「ポインタをn個進めた位置の要素を参照する」ため、結果的には配列と変わらないから
だけど前述の a1 と a2 は違う型なので、そこは注意が必要

たぶん VS Code でC言語の拡張を入れてれば、上記のように書いた変数のところにカーソルを当たるとヒントが出るので、それで確認できると思う
それか実際に動かして sizeof の結果を見るか
2024/09/27(金) 00:16:01.96ID:dEIfxD4z0
>>273
> これの1行目は文字列長によらず固定値にならない?

その通りだよ。 固定値になってたぶん意図通りではない。
その話は >>222 がボコボコに言われてもう終わったよ。
276デフォルトの名無しさん (ワッチョイ d27c-tavX)
垢版 |
2024/09/27(金) 00:20:08.16ID:qUi2cfOF0
もう >>222 を晒すのはやめてあげて......
2024/09/27(金) 00:22:55.64ID:xb00usC10
222は釣りでしょう
2024/09/27(金) 00:23:40.17ID:dEIfxD4z0
あ、ひょっとすると >>273 は話題を誤解してるのか。
「仮引数が配列形式だった場合にポインタに調整されるルール」が話題の中心。
仮引数として現れないと意味ない。
279デフォルトの名無しさん (ワッチョイ 63e3-VZV9)
垢版 |
2024/09/27(金) 07:31:58.10ID:ju4/Ooeg0
>>278
すまん自分が直近のレスだけ見て話題を早とちりしてた
だいたい流れは分かった
280デフォルトの名無しさん (ワッチョイ 2b65-ebyo)
垢版 |
2024/10/15(火) 13:20:49.22ID:+DYHSMWW0
初歩的な質問で申し訳ないんだけど
プログラムをユーザーの入力によって一時停止させるのってどうしたら良い?
pauseで入力待ちにするとかフラグを間に挿入するとかではなくユーザーからの入力があった場合のみ一時停止したい
2024/10/15(火) 13:29:34.78ID:WZg8MP0BM
まずメインの処理を一時停止可能な作りに変える
2024/10/15(火) 13:32:02.14ID:nD7e5Gmv0
>>280
ソースコードの中にファイル名がpauseのファイルが存在するかを判断するロジックを追加
もし存在するならループに入りそれが消えるまで待てばいい
2024/10/15(火) 13:32:39.39ID:WZg8MP0BM
あとコンソールプログラムなのか?
環境を正確に書きな
2024/10/15(火) 13:37:01.44ID:C4BE9tl00
>>280
C は言語として規定している範囲はかなり狭くて、細々とした制御には環境依存の方法が必要になることが多い。
ホスト環境によって作法が違う。
285デフォルトの名無しさん (ワッチョイ 2b65-ebyo)
垢版 |
2024/10/15(火) 13:47:40.16ID:+DYHSMWW0
>>281
根本からなのね
>>282
初心者なもんで、一つのファイル内で完結したら嬉しいなーなんて
>>283
とりあえずコンソールで作ってる
環境はVS2022だけでおk?
>>284
ちょっと前古いサイト参照してたら環境違いすぎて苦労したし古い言語の宿命なんすかね
2024/10/15(火) 13:51:52.41ID:9xoHIO4Lp
環境依存でデバイス依存だからなぁ
2024/10/15(火) 14:34:22.10ID:UH8LrgydM
やりたいことがnon blockingでgetcharしたいってことだとするとwindowsだconsole apiを使う
例えばwindowsのreadline互換実装であるwineditlineを見るといい
2024/10/15(火) 14:36:11.97ID:UH8LrgydM
ただめんどうなので今回のように止めたいだけならこういう簡易的なやりかたがある
ttps://stackoverflow.com/questions/21294713/non-blocking-i-o-in-c-windows
289デフォルトの名無しさん (ワッチョイ 2b65-ebyo)
垢版 |
2024/10/15(火) 20:06:43.67ID:+DYHSMWW0
>>287
一行目の通りで合ってると思う
念の為やりたいことを挙げておくと、メディア再生中の一時停止とかゲーム中のポーズ画面みたいなものだと思ってもらえれば良い
ただ、2行目のreadlineは日本語でググったりヘルプで検索かけたけどよくわからん
>>288
すごい簡単だね、これなら作れるかもしれない
入門書に記載がないのが唯一の不満だよ
2024/10/15(火) 21:39:15.79ID:C4BE9tl00
>>285
言語の古さというより用途だろう。
低レイヤ部分を実装する用途に使う言語だから重厚なランタイムサポートを必要とする機能は入れられない。
2024/10/30(水) 01:54:25.92ID:BzmMNap80
いにしえの議論掘り返してすまんが、>>182の例示による説明が最も本質を突いてるように思う、感謝のレス

文字列リテラルは配列初期化子の構文糖でありながら、また文字列をも表すという二義性を持つ、という云うのはあくまで言語設計の為の汚いハックでしかなかろ?
2024/10/30(水) 10:28:23.97ID:BRGgIRAsp
Cの変数の型指定なんて気休めだからなぁ
2024/11/01(金) 06:24:42.85ID:+lXxXu7p0
気休めじゃなくて気疲れの間違いだろ
長さやsignednessでわけわからん変換しやがるバグの根源と言ってもいい
2024/11/01(金) 11:11:58.05ID:YgeQjLzz0
訳が理解できるようになるまで、お前は使用禁止
295デフォルトの名無しさん (ワッチョイ 622d-CyeO)
垢版 |
2024/11/03(日) 13:27:09.33ID:N1lOck0q0
https://togetter.com/li/1471386
こんな事本当にあるのか?
2024/11/03(日) 13:36:34.35ID:e8fWHn4Q0
もともとバグってたのを対処療法で回避しただけじゃねーの?
そんな驚愕するほどのこととは思わんな
スペースは文字列に加えるってことだろ
2024/11/03(日) 13:45:35.99ID:WzNRcFfL0
ちゃんとソースを公開すればみんなで治してくれるよ
298デフォルトの名無しさん (アウアウエー Sada-GGiU)
垢版 |
2024/11/03(日) 16:06:15.80ID:XxnHrPnRa
バイバイおさるさん
2024/11/03(日) 17:27:36.06ID:4RaSizfZ0
char []s = "うんこ"
s[20] = 0; // どっか判り難いとこにこんなのが紛れてる
回答「(sに)もっとスペースを追加して!」
2024/11/03(日) 17:39:48.03ID:WzNRcFfL0
どこか知らない国で "うんこ" が40バイトくらいある所があったりして
2024/11/03(日) 19:33:15.95ID:/vDzNoeA0
業務だとヨソの担当のモジュールに口出しするのがめんどいから対処療法で握りつぶすみたいなことはあるのかもしれん。
2024/11/03(日) 20:22:14.37ID:5dhdDFeF0
s("※んこ"の値)は読み取り専用になるんじゃないかな
処理系によるかもしれないけど
2024/11/04(月) 01:39:12.77ID:rgFUj3k30
>「ここにスペースを入れてみて」「もっと沢山、もっともっと」
この辺りコピペ怪文書にしか思えないんだが
境界チェックしない言語ならありふれたバグだし、元文書はちんぽとかだったんじゃないだろうか
2024/11/04(月) 13:45:59.93ID:UGhFqLBmp
どうせメモリーリークだろうな
データ位置を変えると現象が変わるなんて典型的だろ
2024/11/04(月) 13:48:37.25ID:nJwTTfVk0
>>302
誤りでした
2024/11/04(月) 14:02:09.24ID:SHEOgeyw0
パンパース当てるのが正しい
2024/11/04(月) 20:44:45.70ID:rgFUj3k30
おむつってあんま進化してないよな
吸収率だとか漏れだとかそんなのは上がってるだろうが、基本的な機能は変わらない
介護業界でも排泄介助っていう高齢者の汚物処理って割と大変な部類だと思うんだが
そろそろおもつ革命を起こさないと業界崩壊するんじゃないの
プログラミングでなんとかできませんかね
2024/11/04(月) 20:51:48.25ID:rgFUj3k30
高齢者に限らず若い子でもうんこ漏らす時は漏らすし、そういう緊急時にも安心できるぐらいのものがそろそろ欲しいな
紙ベースで吸収率だとかで脳が退化してるおむつメーカーではおむつ革命はとても期待できないだろう
2024/11/04(月) 21:52:48.49ID:lap6rdZH0
介護対象に飲ませるうんこがあまり臭くなくなる薬みたいな技術は進化してるぞ
2024/11/04(月) 22:10:34.76ID:TtMQ1IOc0
薬で臭くなくしたうんこだからといって介護対象に飲ませるのはどうかと思うぞ。
2024/11/04(月) 22:15:25.35ID:lap6rdZH0
>>295
こんなんじゃね

#include <stdio.h>
#include <string.h>
#include <limits.h>

int main(void)
{
  char s[] = ""; // ←スペースを11個入れる
  sprintf(s, "%d", INT_MIN);
  puts(s);
}
312デフォルトの名無しさん (ワッチョイ 0920-pds3)
垢版 |
2024/11/04(月) 22:17:04.25ID:lap6rdZH0
>>310
完全に臭くなくなる訳ではないのでおk
2024/11/04(月) 22:57:47.13ID:nqjJRhEX0
ニホンゴ ムズカシイネ
314デフォルトの名無しさん (ワッチョイ 92ad-guIA)
垢版 |
2024/11/05(火) 05:14:52.21ID:srt1vo+S0
逆に考えるんだ。うんこはどうしても出てしまう。だったらそれはそのままにしておけ。
介護する側がそれを気にせず処理出来るのであれば問題は消滅する。だから介護者が
それを気にならなくなるような精神に効く薬を作れば良いんだ。
2024/11/05(火) 06:59:24.91ID:tCS75Iej0
>>295って実行時エラーの話なのかコンパイル時エラーの話なのかもわからなくない?
2024/11/05(火) 15:17:41.47ID:wPeW8RQX0
NASAはネットなんてなかった1970年代にボイジャー1号打ち上げて
240億km離れててもプログラムを送受信してるのに俺らときたら
2024/11/05(火) 21:46:02.31ID:JaQWNq5Na
どうみても脳筋エラー
2024/11/05(火) 21:49:31.93ID:qHb8dozk0
脳筋がCを使いません
2024/11/05(火) 22:03:42.83ID:MR2KM4Hj0
240億kmの伝書鳩
2024/11/06(水) 09:37:06.45ID:csbv8Qbd0
1970年代にもテレビやラヂオはあったわけでね…
2024/11/07(木) 17:53:15.92ID:RjbHlnZn0
1960年代はラジオ少年が秋葉原詣でしてたな
322デフォルトの名無しさん (ワッチョイ 7161-m4Ma)
垢版 |
2024/11/07(木) 22:04:17.92ID:E5qLHtEE0
質問失礼

LPTSTR lptStr = TEXT("テスト");
って書くとE0144とC2044ってエラーを吐くんだがプロパティの文字セットって項目を設定なしにすると正常に処理されるのはどういう理屈なの?
const wchar_t[]からLPTSTRに変換できませんってメッセージ出るし型が違うのかなと思うが
だとしたら何故文字設定いじれば解消するのかもよくわからない
2024/11/07(木) 22:09:23.47ID:QiubzAbP0
LPCTSTR ではダメですか?
当てずっぽうですが
2024/11/07(木) 22:10:11.25ID:QiubzAbP0
>>323
そういうことじゃないのか、ごめんなさい
2024/11/08(金) 09:56:22.05ID:tVfxyvn80
>>322
設定変えても依然エラーだが
VS Community 2022
326デフォルトの名無しさん (ワッチョイ 7161-m4Ma)
垢版 |
2024/11/08(金) 10:31:35.11ID:+8UCAN2P0
>>324
気持ちだけで十分よ
327デフォルトの名無しさん (ワッチョイ 7161-m4Ma)
垢版 |
2024/11/08(金) 10:32:35.47ID:+8UCAN2P0
>>325
2022だと設定項目見つからなかったから2012でやった、そしたら上記の結果になるんすよねえ
2024/11/08(金) 10:36:22.46ID:ce4XJJ6Np
最近のVSはCの当たり前な構文が通用しないから困るよな
329デフォルトの名無しさん (ワッチョイ 7161-m4Ma)
垢版 |
2024/11/08(金) 10:51:18.29ID:+8UCAN2P0
>>328
Visual Studio側の問題なのこれ?
2024/11/08(金) 11:51:09.67ID:y6pbbxPDM
>>327
2022で設定変えたって書いただろ
あほなのか
331デフォルトの名無しさん (アウアウエー Sada-GGiU)
垢版 |
2024/11/08(金) 12:18:22.14ID:F9yTI1pla
LPTSTR lptStr = L"テスト";
332デフォルトの名無しさん (アウアウエー Sada-GGiU)
垢版 |
2024/11/08(金) 12:20:09.93ID:F9yTI1pla
あと
#define UNICODE
#define _UNICODE
だったかな
333デフォルトの名無しさん (アウアウエー Sada-GGiU)
垢版 |
2024/11/08(金) 12:28:34.80ID:F9yTI1pla
それでもだめなら
文字コードが違うんじゃないですかね
334デフォルトの名無しさん (ワッチョイ 7161-m4Ma)
垢版 |
2024/11/08(金) 12:59:02.56ID:+8UCAN2P0
>>330
どストレートな罵倒は久しぶりに聞いたよ
高校上がってからは聞かなくなったけどね
335デフォルトの名無しさん (ワッチョイ 7161-m4Ma)
垢版 |
2024/11/08(金) 13:00:18.41ID:+8UCAN2P0
>>331
ありがとう、だけどダメそうだ
文字コード関連のエラーなんだろうけどどうしたものか
2024/11/08(金) 13:02:23.75ID:Me1tPYCI0
char と wchar_t の不整合じゃなくて const の有無の問題じゃないの?

C++ で文字列リテラルまわりの扱いで仕様変更があったからそれに関係してるのかも?
C++ での文字列リテラルの型は const char[] (ワイド文字リテラルの場合は const wchar_t[]) だが、文字列リテラルから直接変換する場合に限り char* (ワイド文字リテラルの場合は wchar_t*) に暗黙に変換して構わないというルールが C++03 まではあって、このルールは C++11 で削除されたという経緯がある。
つまり C++11 以降は文字列リテラルから暗黙には const を剥がすことが出来ない。 (キャストを書けば出来るけど。)

C では文字列リテラルの型は元から char[] で、 const が付いてない。
だから const まわりの制限とは関係ないんだが、これは C の仕様のほうがおかしいし、 C++ と同様の判定をしたほうが理に適っているとマイクロソフトが考えることはあるかもしれない。
337デフォルトの名無しさん (アウアウエー Sada-GGiU)
垢版 |
2024/11/08(金) 13:18:44.37ID:F9yTI1pla
E0144 エンティティの初期化
型”cont wchar_t *"の値を使用して"wchar_t *"のエンティティを初期化することはできません

C2044は関係無い
338デフォルトの名無しさん (ワッチョイ 7161-m4Ma)
垢版 |
2024/11/08(金) 14:51:25.22ID:+8UCAN2P0
>>336
なるほどね、LPTSTRがchar*だから代入できないって話になるのか
それがわかったらエラー文にかいてあることが理解出来るね

昔の仕様だとconst charに見えて実際は違かったってこと?
それなら今回のコードもエラー吐かないし悩まなくてよかったのに
339デフォルトの名無しさん (ワッチョイ 7161-m4Ma)
垢版 |
2024/11/08(金) 14:52:37.02ID:+8UCAN2P0
>>337
関係ないの?LPSTRに代入できませんって言ってるように見えるけど
2024/11/08(金) 16:25:31.55ID:1lsgaMlnp
signedとunsignedでも怒り狂うからなぁw
いいんだよ、こっちは中身しってんだから余計なエラー吐くなよ
2024/11/08(金) 17:24:12.05ID:Me1tPYCI0
>>338
> 昔の仕様だとconst charに見えて実際は違かったってこと?

C の規格としては本来的に文字列リテラルの型には const は付かない。
これは今も昔も同じ。 変更はない。

なので何かが変わったとしたらマイクロソフトの独自仕様。
私はそのへんに詳しいわけじゃないけど C++ の規格改定に引きずられた可能性は想像できるなぁというぼんやりした予想なので経緯はわからぬ。

でもまあ結果的に const の問題ってのは妥当なみたいだね。
2024/11/09(土) 14:04:43.61ID:L+GgUCLJ0
LPTSTR lptStr = (LPTSTR)TEXT("テスト"); で警告出たりするのかな?
糞面倒だけどキャストで通るならそれ以上の対応不用
2024/11/09(土) 14:22:07.15ID:12zpUv7J0
VS使ってるからたぶんCじゃなくてC++
こういうボンクラの自覚ないボンクラは相手しても疲れるだけ
344デフォルトの名無しさん (ワッチョイ 7161-m4Ma)
垢版 |
2024/11/09(土) 18:12:46.73ID:IeEwNzSH0
>>341
理解した
constは付かないはずなのにリテラルにVisual Studioが勝手に付いてることにしてくるってことね
わざわざありがとうスッキリしたよ
345デフォルトの名無しさん (ワッチョイ 7161-m4Ma)
垢版 |
2024/11/09(土) 18:13:16.97ID:IeEwNzSH0
>>342
いけた
たしかに面倒だけど仕方ないね
346デフォルトの名無しさん (ワッチョイ 7161-m4Ma)
垢版 |
2024/11/09(土) 18:17:26.89ID:IeEwNzSH0
>>343
そんなこと言いながら何回もレスくれるなんて
2024/11/09(土) 18:29:31.05ID:mxjkBfxb0
>>315
どっちもいける

実行時エラー
https://wandbox.org/permlink/r9w30EwoyKVxIguC
> Segmentation fault

コンパイル時エラー
https://wandbox.org/permlink/yPJz2UPs8xHYPLAr
> prog.c: In function 'main':
> prog.c:8:17: error: '%d' directive writing 11 bytes into a region of size 1 [-Werror=format-overflow=]
> 8 | sprintf(s, "%d", INT_MIN);
> | ^~
> prog.c:8:5: note: 'sprintf' output 12 bytes into a destination of size 1
> 8 | sprintf(s, "%d", INT_MIN);
> | ^~~~~~~~~~~~~~~~~~~~~~~~~
> cc1: all warnings being treated as errors
348デフォルトの名無しさん (ワッチョイ cdd5-MfT4)
垢版 |
2024/11/10(日) 00:27:12.07ID:dkv1a77w0
左辺をLPCTSTRにすれば良くない?
リテラルの文字列を可変にすること自体が本来は不要だし、右辺を可変にキャストするよりは左辺を不変として (LPCTSTRとして) 受け取れば良いと思う
2024/11/10(日) 09:35:26.26ID:a6nPaG4v0
>>344
オンラインコンパイラで VS17.10 を確かめてみたが文字列リテラルには const は付かないぞ。
お前が間違って C++ を使ってるという >>343 の意見に一票。
2024/11/10(日) 15:28:44.44ID:E/UouhcZ0
>>322
・Microsoft Visual Studio Community 2022 (64 ビット) を使用し「C++コンソールアプリ」で新規プロジェクト作成
・ソリューションエクスプローラーでソースファイルにあるファイル名を*.cppから*.cへ変更
・ファイル名を変更したファイルに下記をコピペ
#include <windows.h>

int main(void)
{
LPTSTR lptStr = TEXT("テスト");
}
・ビルド(B)→ソリューションのビルド(R) でフツーにビルド通ったわ。
351デフォルトの名無しさん (アウアウエー Sa13-vkNS)
垢版 |
2024/11/11(月) 11:10:09.47ID:RXw/cl7Za
つまりスレタイ嫁ということか
2024/11/11(月) 11:32:56.82ID:CKwZRMfb0
>>343 は速攻ぶったたいてるが、学生か初学者はこういう経験しとくもんだ
Cは汗に似て泥臭いんだよ

俺もあとで追試しよっと テキトーでやってて知識整理できてないわ
2024/11/12(火) 18:11:56.60ID:bmRwPCyO0
>>322
コンパイラオプションを見れば明らかになるじゃろう。
354デフォルトの名無しさん (JP 0H93-qgn8)
垢版 |
2024/11/13(水) 18:56:16.48ID:5p447UHqH?2BP(1000)

EchoAPIがVS Codeのワークフローにピッタリで、APIテストの能力がグッとアップしったって聞いて
355デフォルトの名無しさん (アウアウエー Sa13-vkNS)
垢版 |
2024/11/15(金) 18:07:01.60ID:yZ5Bkpe2a
まるちんこしね
2024/11/22(金) 19:50:13.47ID:KyG89VCU0
Q.
doubleをprintfで表示するには%lfでいいの?

A.
double 型を printf で表示する場合、%lf ではなく %f を使用するのが一般的です。

理由:
printf の可変長引数において、float 型は double 型に自動的に昇格されます。
そのため、%f は double 型の値も受け取ることができます。

%lf は scanf で double 型の値を読み込む際に使用されますが、
printf では %f と同じ意味として扱われます (C99規格以降)。
357デフォルトの名無しさん (ワッチョイ bf5f-FO3g)
垢版 |
2024/11/24(日) 19:40:17.88ID:g9nxxeRj0
これが同じ値書いてくれないのは普通だったんだっけ.

#include <stdio.h>

int main() {
int s=31;
unsigned long i = 1 << 31;
unsigned long j = 1 << 31;
unsigned long k;

while(i) {
k = 1 << s;
printf("%lu,%lu,%lu¥n",i,j,k);
i = (unsigned)i>>1;
j >>= 1;
s--;
}

return 0;
}
2024/11/24(日) 19:55:59.76ID:VUrUqN1f0
手元にあるGCCとMS-C(32bit)は
同じ値が出てました
359デフォルトの名無しさん (ワッチョイ d7d8-7ouQ)
垢版 |
2024/11/24(日) 20:09:10.15ID:KIy2cazo0
質問失礼します
ダイアログボックスについて学習しようとしているのですが、サンプルのリソースをコピペしたところ、ダイアログボックスのIDが認識されなく手詰まりになってしまっています。
どなたかご助力ください。

TEST DIALOG (座標を書くと書き込みできない)
C2059
C2061

以上のソースでエラーを吐いてしまいます。リソースをベタ打ちで記述する参考サイトが少ないので判断がつきません。
2024/11/24(日) 20:28:06.09ID:VUrUqN1f0
記述に文法上の誤りがあるって事です。
コピペで失敗しているのか、
元々のサンプルに誤りがあるかは
これだけでは分かりません
文法の基本から学び直して
自分で見つけるしかないかもしれません
361デフォルトの名無しさん (ワッチョイ bf5f-FO3g)
垢版 |
2024/11/24(日) 20:47:32.93ID:Hl1pEu0p0
>> 358
試していただきありがとうございます.
FreeBSD clang version 18.1.6 (https://github.com/llvm/llvm-project.git llvmorg-18.1.6-0-g1118c2e05e67)
Target: x86_64-unknown-freebsd14.1
と,gccは共に jの値がおかしいのです.
試しに,
unsigned long j = 1 << 31;

unsigned int j = 1 << 31;
にすると同じ値になる.

これはコンパイラのBUGかなぁ.
2024/11/24(日) 22:17:04.46ID:/KMFo2rr0
よく分からないけど
unsigned long i = 1 << 31;
unsigned long j = 1 << 31;

unsigned long i = 1L << 31;
unsigned long j = 1L << 31;
とするとうまくいく? clang

どちらでも同じ結果になりそうだけど
見当違いだったらごめんなさい
2024/11/24(日) 22:25:28.27ID:/KMFo2rr0
gcc -S
でアセンブラ出してみてみたけど、
いや、アセンブラよくわからないんだけど、
修正前の iと jは初期化時にいずれも符号拡張されて大きな値になっていて
その後なぜか iの方は下32ビットで、jの方は64ビットで計算されているようで、正しいのはむしろ jのように見えたがごめんなさい
本当にアセンブラ分からないので多分間違ってます…
2024/11/24(日) 22:26:25.59ID:zY64cYUd0
gcc, clang
sizeof(int) == 32
sizeof(unsigned long) == 64
での出力

18446744071562067968,18446744071562067968,18446744071562067968
1073741824,9223372035781033984,1073741824
536870912,4611686017890516992,536870912

省略

8,68719476728,8
4,34359738364,4
2,17179869182,2
1,8589934591,1

これはこれで正しいと思うが
2024/11/24(日) 22:45:06.29ID:/KMFo2rr0
あ、iは unsigned (int)でキャストしてるのか
366デフォルトの名無しさん (ワッチョイ bf5f-FO3g)
垢版 |
2024/11/24(日) 23:09:31.94ID:Hl1pEu0p0
わかりやすく,intのものとcastかけたのにしてみました.
これだとやはり,pの値だけ変でした.

元々は,binaryで数を8bit 16bit 32bitで表示する関数が,8,16が普通で32だけ変なので気がついたのでした.なんでintだと符合拡張されなくてlongだとされるかが謎.

#include <stdio.h>

int main() {
int s=31;
unsigned long i = 1 << 31;
unsigned int j = 1 << 31;
unsigned long p = 1 << 31;
unsigned long k;

while(i) {
k = 1 << s;
printf("%lu,%u,%lu,%lu¥n",i,j,k,p);
i = (unsigned)i>>1;
j >>= 1;
p >>= 1;
s--;
}

return 0;
}
367デフォルトの名無しさん (ワッチョイ bf5f-FO3g)
垢版 |
2024/11/24(日) 23:16:12.94ID:Hl1pEu0p0
unsigned long p = 1 << 31;

unsigned long p = 1L << 31;
にしたら同じ値になりました.

ううむ,なぜ
unsigned int j = 1 << 31;
だとうまくいって,longだと1Lにしないとうまくいかんのだ.
2024/11/24(日) 23:36:41.28ID:BVpPJ8iH0
右辺が 1<<31だと
左辺が intだと0x80000000がそのまま、
longだと 0xffffffff80000000に拡張されて転記されるからでは
2024/11/24(日) 23:49:31.80ID:BVpPJ8iH0
unsigned long i = (unsigned long) 1 << 31;
とすれば iは 0x80000000になるかと
2024/11/24(日) 23:50:27.79ID:BVpPJ8iH0
1lとするのと同じだけど
2024/11/25(月) 02:42:55.67ID:EAdMpn4b0
>>367
言語仕様的に解釈すると……

シフト演算子の結果の型は左オペランドを整数拡張した後の型と同じになる。
整数リテラルは int の範囲で表せる限り int なので 1 は int 。
int は整数拡張の必要がないので 1<<31 の結果の型も int 。

そして結果の型が signed かつ結果の値が結果の型で表現可能な範囲にないときの動作は未定義なので
2147483648 が int (おそらく質問者の環境では 32 ビット) の最大値である 2147483647 を越えていて未定義の挙動となる。

不定とか処理系定義ではなく未定義と明記されてる。
つまり言語仕様上は何が起きても良いということ。
2024/11/25(月) 07:22:58.48ID:NtppUMW10
6.3.1.3のこれじゃないの
Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or
subtracting one more than the maximum value that can be represented in the new type
until the value is in the range of the new type.
373デフォルトの名無しさん (ワッチョイ bf5f-FO3g)
垢版 |
2024/11/25(月) 08:27:04.40ID:qsrJNZhH0
6.3.1.3

符号付き整数型及び符号無し整数型 整数型の値を̲Bool型以外の他の整数型に変換する場合,

その値が新しい型で表現可能なとき,値は変化しない。

新しい型で表現できない場合,新しい型が符号無し整数型であれば,新しい型で表現しうる最大の数に

1加えた数を加えること又は減じることを,新しい型の範囲に入るまで繰り返すことによって得られる値

に変換する(49)。

なるほど,1がintで<<31すると負の最大値となって,unsignedとして表せないからか.

皆様,ありがとうございました.
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況