X



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
2025/03/12(水) 22:07:09.85ID:/p3tzJNRp
AIは何も指定しなきゃjavaやpythonやC#のコードを吐き出すよ
2025/03/18(火) 10:34:05.62ID:mIJI9ibF0
cはむずい定期
2025/03/19(水) 20:09:43.41ID:WDKEEomI0
文法的にはポインタ周りが(少し)難しいだけ
個人的にはpythonの方が難しく感じるな
2025/03/19(水) 20:44:03.52ID:SWZJHd7L0
C が未定義をエラーとして補足せずに黙って変になることがあるのは入門書などをまともに読まずにいろいろ弄って学ぶタイプの人には向いてないな。
ちゃんとした入門書をちゃんと読むならそんなに難しいわけではない。
しかし難しくないことでもしょうもないミスをするのが人というものだという現実もあって、特に規模が大きくなると C はしんどい。
難易度とかいうのとは別の話として、理解していても間違う。
726デフォルトの名無しさん (ワッチョイ 13ad-avMV)
垢版 |
2025/03/20(木) 04:57:02.69ID:07u24rkx0
まあしかしこの頃のコンパイラは警告やエラーを沢山出してくれて分り易いよ。
昔のはチェックが緩くて出なかったからな。
その状態から gcc で printf() のフォーマットと引数のチェックが出来ると知った時は衝撃を受けた。
2025/03/20(木) 17:01:49.87ID:iinwNT6F0
>>726
それな、オプションさえちゃんと付ければ昔でもできてたよ
2025/03/20(木) 17:31:14.06ID:PqZkwPwR0
GCC では遅くても 2.95.3 には attribute で文字列が書式であることを指定できて型チェックする機能はあった模様。(2001年頃)
https://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC84
ただな、このスレにいるようなおじさんの言う「昔」は 1980 年頃の話だったりするんよ。
MS-DOS 用とか CP/M 用とかのコンパイラの話なんよ。
2025/03/20(木) 17:39:11.70ID:Enps6Akh0
その年代の人はおじさんじゃなくておじいさんでは
2025/03/20(木) 17:45:05.08ID:iinwNT6F0
>>728
スマソ、俺はちょっと若すぎたわ
だいぶ昔からできてた記憶があったがそれよりさらに昔の話とは恐れ入った先輩
2025/03/20(木) 18:23:15.20ID:0dSk8Oyx0
メインフレームにダム端末繋げてた時代じゃよ
2025/03/20(木) 23:54:14.30ID:t3XlSG3jd
gcc7.1から突然エラーメッセージが親切になったのはあるな
ちょうどclang+llvmが話題になった時期でそれに対抗したらしい
733デフォルトの名無しさん (ワッチョイ 13ad-avMV)
垢版 |
2025/03/21(金) 07:44:18.11ID:6cMMiEqo0
>>727
それはどのぐらい昔かによる。
80年代後半にはまだなかったと思う。
734デフォルトの名無しさん (ワッチョイ 13ad-avMV)
垢版 |
2025/03/21(金) 07:45:09.98ID:6cMMiEqo0
>>728
そうそう。80年代。
2025/03/21(金) 08:19:02.26ID:kfFumR870
真理子版が便利すぎた。
2025/03/22(土) 13:52:41.80ID:A90b+kK90
他人にも使わせるツールに環境変数「真里子」はキモすぎてビビった
737デフォルトの名無しさん (アウアウエー Sa23-D2PX)
垢版 |
2025/03/22(土) 14:25:25.39ID:U6/Lg1xxa
>>728
scanf, sscanf で float, double に %f, %lf のところを %f, %f にしてバグるのがありがち
738627 (ワッチョイ 5377-avMV)
垢版 |
2025/03/22(土) 15:31:32.91ID:7ZrFn0ve0
scanfなんて使ったことねーや
ありがちってほど使ってるんか
2025/03/22(土) 15:40:39.16ID:8J5Eq6PC0
scanfに道に落ちているを食べさせてはいけません
740デフォルトの名無しさん (ワッチョイ 492a-jhJX)
垢版 |
2025/03/28(金) 08:23:03.00ID:+OZuQWBg0
この警告、環境によっては出ないの?

$ cc ld.c -Wall
ld.c: 関数 ‘main’ 内:
ld.c:6:19: 警告: 書式 ‘%d’ は引数の型が ‘int’ であると予期されますが、第 2 引数の型は ‘off_t’ {aka ‘long int’} です [-Wformat=]
  6 |  return printf("%d", offset);
   |         ~^  ~~~~~~
   |          |  |
   |          int off_t {aka long int}
   |         %ld
$ cat -n ld.c
   1 #include <stdio.h>
   2 #include <sys/param.h>
   3
   4 int main() {
   5  off_t offset = 1;
   6  return printf("%d", offset);
   7 }
   8
2025/03/28(金) 08:29:47.68ID:v2Oxq7uoM
おれの作ったCコンパイラはそんな警告出さないけど何か文句ある?
742740 (ワッチョイ 492a-jhJX)
垢版 |
2025/03/28(金) 09:29:48.60ID:+OZuQWBg0
>>741
あー、なるほど。↓よ。

$ cc --version
cc (GCC) 14.2.0
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
2025/03/28(金) 11:25:13.48ID:gM96YdDw0
>>740
出さないコンパイラはあるし、その場合に警告を出すコンパイラであっても printf 類を特別扱いしてなんとかしてるので、可変長引数一般では型が合わないときに検出されない。
744740 (ワッチョイ 492a-aKLX)
垢版 |
2025/03/28(金) 13:15:49.58ID:+OZuQWBg0
なるぽろ。%ld に変更せず、放っておくか。ありがとう。

ちなみに、逆に、%ld だと警告する場合も有り得るのだろうか。例えば off_t が非 long の機種があるとか。
2025/03/28(金) 13:32:37.75ID:gM96YdDw0
x86-64 なら System V ABI ではどうせ 64 ビットレジスタで受け渡されるからそこんところでは問題にならないのだが、最適化したときにどうなるかまるで予想がつかない。 放置してよいとは言えない。

いったん intmax_t にキャストするのが正当な方法だと考えられている。
https://www.jpcert.or.jp/sc-rules/c-int15-c.html
746デフォルトの名無しさん (ワッチョイ 6eef-29WZ)
垢版 |
2025/03/28(金) 15:39:13.17ID:Gm0qUC0n0
struct X* x;で自動変数を定義した場合
スタック上のどこかにstruct Xの領域が確保されたりしますか?
2025/03/28(金) 15:47:02.39ID:v2Oxq7uoM
されない
2025/03/28(金) 17:27:47.76ID:+OZuQWBg0
>>745
> printf("%ju", (uintmax_t) x);

なるぽろ。ありがとう。
2025/03/28(金) 19:09:11.37ID:Yj8GIx0sp
なんだよjって、何の略だ?
2025/03/28(金) 22:16:42.65ID:gM96YdDw0
>>749
なんらかの単語の略 (頭文字) というわけではないらしいよ。
> j is sort of like "i" for integer
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n833.htm
2025/03/28(金) 23:06:36.11ID:UFqBPtr80
μ→uみたいなものか

大文字の I はもう使われてふのかな?
752デフォルトの名無しさん (アウアウウー Saa5-WcQO)
垢版 |
2025/03/29(土) 16:07:35.02ID:M3jsTRd4a
long long や unsigned long long の出力に %lld や %llu って昔は使えてた気がするが
最近はだめなんかな
%I64 とか %U64 みたいなのになってるん
2025/03/29(土) 16:54:36.19ID:HRez4USp0
>>752
I64 とかはマイクロソフトの拡張。
新しい方法じゃなくてむしろ古い方法が互換性のために残されているだけ。
今となってはあえて使う理由はない。
754デフォルトの名無しさん (ワッチョイ 2e2a-aKLX)
垢版 |
2025/03/29(土) 17:30:28.12ID:bd7PveSA0
>>752
> %I64 とか %U64

移植が大変そうね。
2025/04/08(火) 18:05:53.82ID:f9O97Hv70
sudo で実行すると execl が動作しないように見える。なぜ?
$ cat -n e.c
   1 #include <stdio.h>
   2 #include <unistd.h>
   3
   4 int main() {
   5  pid_t pid;
   6  if ((pid = fork()) > 0) return 0;
   7  else if (pid < 0) return 1;
   8  execl("/bin/bash", "/bin/bash", "-c", "echo $$ $PPID >> /tmp/log", NULL);
   9  _exit(2);
  10 }
$ gcc -g e.c
$ ./a.out
$ cat /tmp/log
10593 1566
$ sudo ./a.out
$ cat /tmp/log
10593 1566
$
756627 (ワッチョイ 22ca-VGeA)
垢版 |
2025/04/08(火) 19:31:31.59ID:HmugccjD0
まずコピーするなら手を入れるな手を入れると他も全部疑わなきゃいけなくなる
それからsudo -E ./a.outとsudo strace ./a.outを試せ
757デフォルトの名無しさん (ワッチョイ 798a-GhsC)
垢版 |
2025/04/08(火) 19:45:35.63ID:dAM9KaxA0
縦の数字はなに?
普通にエラーになるだろそれ
2025/04/08(火) 20:08:58.79ID:0fraKCca0
catの引数に-n指定してるからだろ
759デフォルトの名無しさん (ワッチョイ 4dc4-xzp7)
垢版 |
2025/04/08(火) 20:57:19.94ID:brzdTu7q0
手元にあるfedora で試したが、
sudo ./a.out の結果表示は2行になった
多分、正常に処理できたようだ
2025/04/08(火) 22:40:53.76ID:NxLLuNcW0
うちはダメでした
>>755 と同じような結果です
ubuntu22.04 lts
2025/04/08(火) 22:43:01.77ID:NxLLuNcW0
あ、次のようにしたときです
sudo ./a.out

/tmp/log に追記されませんでした
762755 (ワッチョイ a92a-ZtHn)
垢版 |
2025/04/08(火) 22:49:40.17ID:Rmhs1Vne0
>>759
えー!? と別環境で実行したら、sudo でも execl が動作したように見える。なにこれ。

$ ./a.out
$ cat /tmp/log
13706 1
$ sudo ./a.out
$ cat /tmp/log
13706 1
13721 1
$

取り敢えず、うちの Ubuntu の「おま環」問題のようでした。お騒がせしました。
ただ、今回のは bash の $PPID が init (1) になるという新たな謎が...
2025/04/09(水) 00:22:33.67ID:06ntJanv0
親プロセスが先に死んだら子は init の養子になる。
だけどこの場合だとどちらが先に死ぬかはプロセスのスケジューリング次第で状況によるってことなんじゃないのかな。
Linux の事情はよく知らんけど。
2025/04/09(水) 00:23:29.81ID:Z/QH/Jgt0
Linux 板で聞いた方が回答ありそうな気がする。
765デフォルトの名無しさん (ワッチョイ ae7e-GhsC)
垢版 |
2025/04/09(水) 15:00:16.84ID:cB69i6Vg0
const unsigned char t100_day[3807] PROGMEM = { 0x89, 0x50, 0x4e, 略, }
const unsigned char t100_night[3568] PROGMEM = { 0x89, 0x50, 0x4e, 略, }

String tenki_i = "01";

char*const unsigned char t100_day[3807] PROGMEM = { 0x89, 0x50, 0x4e, 略, }
const unsigned char t100_night[3568] PROGMEM = { 0x89, 0x50, 0x4e, 略, }

String tenki_i = "01";

char* y_icon; // FIXME 型が分からない

if (tenki_i == "01") y_icon = "t100_day";
else if (tenki_i == "01_n") y_icon = "t100_night";
else if (tenki_i == "08") y_icon = "t200_day";
else if (tenki_i == "08_n") y_icon = "t200_night";
else y_icon = "t999_day";

sprite.drawPng((std::uint8_t*)y_icon, sizeof(y_icon), 0, 25);


t100_dayなどは画像なんですけど、tenki_iの中のstrによって画像を変えたいです。
y_iconはどうやって指定したらいいでしょうか?
766デフォルトの名無しさん (ワッチョイ ae7e-GhsC)
垢版 |
2025/04/09(水) 15:01:47.32ID:cB69i6Vg0
>>765
コピペ間違えました
正しくは以下です


char*const unsigned char t100_day[3807] PROGMEM = { 0x89, 0x50, 0x4e, 略, }
const unsigned char t100_night[3568] PROGMEM = { 0x89, 0x50, 0x4e, 略, }

String tenki_i = "01";

char* y_icon; // FIXME 型が分からない

if (tenki_i == "01") y_icon = "t100_day";
else if (tenki_i == "01_n") y_icon = "t100_night";
else if (tenki_i == "08") y_icon = "t200_day";
else if (tenki_i == "08_n") y_icon = "t200_night";
else y_icon = "t999_day";

sprite.drawPng((std::uint8_t*)y_icon, sizeof(y_icon), 0, 25);


t100_dayなどは画像なんですけど、tenki_iの中のstrによって画像を変えたいです。
y_iconはどうやって指定したらいいでしょうか?
767デフォルトの名無しさん (スッップ Sd22-yI6P)
垢版 |
2025/04/09(水) 15:16:14.76ID:qDwL9bg0d
>>755もそうだし書いちまったもんはしょうがねーけどコードを載せる時は
どうしろこうしろって書いてあんだから従えよ
アンタどこ行ってもそんな感じなのか?
768デフォルトの名無しさん (ワッチョイ 79f9-GhsC)
垢版 |
2025/04/09(水) 15:24:40.77ID:Hnk7Q6m60
すみません、書き直しました
https://ideone.com/CSy0Nb

t100_dayなどは画像なんですけど、tenki_iの中のstrによって画像を変えたいです。
y_iconはどうやって指定したらいいでしょうか?
2025/04/09(水) 15:27:10.13ID:lI8vd/RJ0
>>755
fork呼んだ親プロセスがreturn 0でいきなり終わってるのがダメ
wait呼んでプロセスの終了待ちしろ
2025/04/09(水) 18:01:06.77ID:06ntJanv0
>>768
その断片的なプログラムではよくわからんが型を合わせるだけなら y_icon の宣言はこうなるべきだと思う。

const unsigned char* y_icon;
2025/04/09(水) 18:30:26.27ID:06ntJanv0
>>768
ところでそれは C++ じゃない?
なんでこのスレで聞くの……。
772755 (ワッチョイ 6e2a-ZtHn)
垢版 |
2025/04/09(水) 19:53:07.12ID:dFJfWRF+0
>>769
「お騒がせしました。」と言ったので、勝手ながら質問を終えた気がしていた。見てくれて有り難う。

>>755,762 については、Ubuntu においても sudo で execl は動作していた。
動作しないように見えたのは、Ubuntu 特有のファイル権限設定があり、root といえどもファイルにアペンドできないせいだった。Qiita にあったサマリが解りやすい。

https://qiita.com/skyflare2001/items/1c1934b1d2f405228334#2025118-追記
> Ubuntu の /tmp のユーザファイルに root で追記できない

全く C言語に関係なかった。ごめんちゃい。
レスを投稿する

5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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