C言語なら俺に聞け 149
■ このスレッドは過去ログ倉庫に格納されています
自分を賢いと思っている馬鹿は
周りが自分をどう見ているかも
相手がどのレベルにいるのかも
なぜ自分が放置されてるのかも
何一つ知らない musl-libcみたいに,特定のOSのプロジェクトではないPOSIXユーティリティの実装ってありますかね。 strtok_sを4変数にするとエラーになるんですけどどうしたらいいですか?
strmaxがある説明と無い説明があってわからないです。 >>6
msvcのstrtok_sは非標準だから、_MSC_VERとかが定義されてるかどうかで呼び分けるしかないね。
あんまり覚えてないけどmsvcバージョンのほうが先にあった気がするから、iso/iecが悪い気がする。(間違ってるかも)
まあmsが切り替えスイッチを用意してくれればよいのだけど。 >>7
よくわからないのでstrtokを使いました。 ちょっとお知恵を拝借。
符号付き14ビットの整数があるとき(14ビットのMSBが符号ビット)、その値を符号付き16ビット値に拡張するうまいやり方はないでしょうか?
拡張後も符号や数値自体は変化なしです。
例えば2進で
10 1010 1010 1010
という符号付き14ビット値があった時、
1110 1010 1010 1010
のように変換したい。
14ビット値を16ビット符号付き変数に入れて左に2ビット論理シフトし、さらに右に2ビット算術シフトすれば実現できるのですが、何となく気持ち悪くて。
サクッとエレガントな方法はないでしょうか? >>9
2の補数表現として…
普通に14bit目が1なら0xc000とorするだけじゃないの? もはや答えが出切ったと思うので斜め上からの回答でも書いておくか。
回答
int型が14ビットの整数型になっているCコンパイラを使う。
もちろんchar型は7ビット。
CPUは1バイトが7ビットである。 それ16bitの結果得るのが面倒なだけだろ
もう少し面白い回答頼むわ 皆様回答ありがとうございます。
今回はビットシフト方式で行こうと思います。
>>12
使ってるCPUとコンパイラがマイナーな、ある意味純粋な16ビット環境で、sizeof(char)もsizeof(short)も1を返し、sizeof(long)は2を返すような特殊な環境なので7ビットマイコンではありません。 60〜70年代メインフレームは百花繚乱だったなぁ
ttps://en.wikipedia.org/wiki/Word_(computer_architecture)
27bitマシンとかどーすんだよ このように1バイトが何ビットかはアーキテクチャ依存のため、EUではハードディスクなどのパッケージにはGB単独表記は認められず、Go(ギガオクテット)を併記または単独で表記しなければならない。
1オクテットは必ず8バイト。 大丈夫。
文脈から理解はしてる。
上げ足取りなだけだ。 バグってそういうもんだろ
笑ってられる神経が異常だ >>12
CHAR_BIT は 8 以上、 INT_MAX は 32767 以上って規定があるから、規格非準拠になっちゃう。 C89止まりのものです
私のような者が C11などの新しい規格を学ぶのによい書籍はありますか? このスレは最近独り言が増えたのか?
オレもそうだがな >>27
>C89止まりのものです、私のような者が C11などの新しい規格を学ぶのによい書籍はありますか?
私もC89止まりですが、それで困ることがあるのでしょうか? >>29
私はC99で止まっていますが、最近はもっぱらPythonを使っているので困りません pythonいいよな
yieldとかC標準にもほしい cpythonのyield実装を見ればC言語に移植できるんじゃねえの 動き的にgets的な動きする。
表示したら即メモリ解放的な。 >>31-32
yieldはソース上に出ないデータを管理しないといけないからC言語の理念と合わない気がする
※ 個人の感想だが…
C++には欲しいな yieldはいわばスタック情報の保存だから、setjmp、longjmpで出来そうな出来なさそうな? 単にコンテキスト保存するだけだからまあ再現はできるよ
書き方としてイテレータとか欲しいのはわかるけど実現方法はどうでもいいわけじゃん POSIXの<errno.h>にある番号とBSDの<sysexits.h>で全然番号が違うのは理由があるのかな。
いままで<sysexits.h>に従って「許可がない」動作は77を返すものだと思ってたら
Linuxでは1を返すのでなぜだと思って調べたら<errno.h>では権限エラーは1。
嫌だなぁ。 77とか1とかのリテラルで書くバカって今でもいるんだ… >>40
<errno.h> の方はC言語でシステムコールしてエラーになった時の errno 変数の値で、
<sysexits.h> はプログラムが exit() 等で終わる時に使う値なので全く用途が違う。 >>43
つまり<errno.h>で定義された値はユーザーからは見えないんだね。 >>44
見えないというか、ただの数値なのでどこにでも使えないわけではないが、errnoの値をexit()で返す事は想定して作られていない。 >>45
わりとerrnoを返してくる人多いけどね #defineマクロ定数はプリプロセッサで単純置換されるだけだからな >>46
多いか?
別にそう作っちゃいけないということはないが、できれば exit() では <sysexits.h> の方を使って欲しいな。
単なる個人的な希望だが。 >>45
>>46
ありがとう。
ユーティリティ自体の終了ステータスはPOSIXの範囲では0もしくは非0,
BSD拡張で<sysexits.h>で定められている値を使えば まあユーザーの助けにはなるって認識でいいかな。 struct S {
size_t len;
type-X buf[0];
};
という状況下で、
size_t const len = 500;
struct S* const p = (struct S*)malloc(sizeof(struct S) + sizeof(type-X)*len);
p->len = len;
p->buf = (type-X*)((size_t)p + sizeof(struct S));
という処理を偶に見かけますが、これだと末尾パディングの影響でbuf[1]のアドレスがtype-Xのアライメントに沿っていない可能性があるので、不正な気がします
具体的には
struct S {
size_t len;
type-X* buf;
};
として、
size_t const len = 500;
size_t const padding_for_align_x = alignof(type-X)*(sizeof(struct S)%alignof(type-X) == 0 ? 0 : 1);
struct S* const p = (struct S*)malloc(sizeof(struct S) + padding_for_align_x + sizeof(type-X)*len);
p->len = len;
p->buf = (type-X*)((size_t)p + sizeof(struct S) + padding_for_align_x);
...などとしないとアライメント違反になりそうな気がするのですが、この認識は正しいでしょうか すいませんよく考えたら自己解決しました
>>52の質問は取り下げます
お騒がせしました >>4
へー。musl-libc知らなかったけど組込Linuxとかの界隈では有名っぽいね。
ソース見たけどすごく短かいのが多くて逆に不安になったw sysexits.h って初めて知った
>>49
Linuxとかだと ls unko で 2 が返るとか割と普通 >>55
まあBSDでプログラミングしたことないと あんまり知りえないと思うわ。
だいたいPOSIXで定められてる訳じゃないから 知っておくべきなのはBSDプログラマくらい。
ただLinuxプログラムのエラーコード周りはなぜか非統一的なんだよね。
GNUコーディング規約で事細かに決められてそうなものだけどねw
apt(1)なんて権限エラーに100返すんだぜ? >>52
『MSDNこそC++である』という格言があるように、構造体の末尾の配列は不定長に出来ます
構造体内の可変長配列
ttps://msdn.microsoft.com/ja-jp/library/b6fae073(v=vs.120).aspx VLAとは違うんだよな
そのページのサンプルに限っては不完全型配列の直前にサイズ情報があって確かに可変長だが
配列そのものがサイズ情報を含むのではないので、不定長とでもいうべきものだ どうでもいいけど そのURLの書式はなんだ?
URLパラメータってそんな位置に置けたっけ。 先頭さえ確定できれば後ろなんてどうでも良い
さすがのC言語さん >>57
その格言は初めて聞きましたw
その方法だとアライメント違反になるかならないかが気になっていたのですが、
* 末尾のbuffer[0]でその型のアライメント以上のアライメントを構造体に強いることができる(拡張)
* 末尾のbuffer[1]の場合は当然構造体にそのアライメント以上のアライメントを強いることができる(c89)
* 末尾のbuffer[]でも同様(c99での仕様)
となり、全パターンでbuffer[i]へのアクセス時にアライメント違反にならないので、
ポインタメンバにしてアライメント気にしてmallocする必要ないのかー、これでいいのかーと解決した次第です
>>58
英語だとflexible arrayでした >>59
v=vs.120のとこ?
クエリストリングちゃうやろ >>55
ま、確かにコマンドごとにバラバラだな。
errno とも無関係だったりする。 もうちょっと皆がリターンコードについて考えてくれたらいいね。 コマンドの戻り値って、皆さんどの様に活用されてますか?
成功か失敗か、それが分かれば十分な気はしますけど >>65
例えば同じ「失敗」でも何が原因なのか分かったほうが問題に対処しやすくない?
ファイルが存在しないのか はたまたファイルが現状の権限では読みとれないのか。
もちろんエラーメッセージを見てもいいけど。
あと,終了ステータスを見ないと成功失敗が分からない場合がある。
例えばdiff(1)ユーティリティーなんかは「1」という(一見失敗してるような)終了ステータスに
「(コマンド自体は成功してるが)不一致が発見された」という意味を割り当ててる。
fsck(1)ユーティリティーはもっと複雑。
まあ知ってるに越したことはないし<sysexit.h>はPOSIX標準ではないにせよ,
Unixプログラミングをする場合は積極的に利用してもいいかも。 イヤ、使い方の可能性としてそう言うものがあるくらいは知っている
実際に使っている人がいたら、どういう使い方をしているかを聞きたいんだ 勘違いしてましたわ
俺の知ってる限りじゃシェルスクリプトでは多用されてるがCではどうだろうね。あまり見掛けない。 #define elif(e) else if (e)
みたいにして
if (...) {
...
} elif (...) {
...
} else {
...
}
↑こういう感じにするのってやっちゃマズいのかな。
個人的にelifキーワードがある言語に慣れてるんでこうやってて
現状特にエラーに遭遇したことはないんだけど
OSSのソースコードとか個人が公開してるソースコード見ても
こういうことやってないんだよね。 >>70
やめとけ
メリットが1ミリもないから誰もやらない。
善し悪しはさておき、C言語での判断基準はほぼ「実行性能」であって、
else if と書けばいいだけの所をいちいちマクロにする馬鹿なんて世界中に誰もいないだけ。
というか、そのレベルで慣れられないのなら、elif言語だけ使っておけ。 #define { begin
みたいなことを本気でやる奴がいたとはw ソースコードを静的解析する関係で、文法を強引に変えるような変態な前処理は良くないらしい。 世の中の静的解析ツールは当然プリプロセッサ適用後の状態で解析するわけで typedefも避けるという流儀はあるからね
まあ気持ちはわかる
むしろGNU拡張のtypeofはアリ >>73
endは普通に変数名に使われてるから無理だな。
それはさておき、セミコロン嫌いも拗らせておかしくなってるよな。 >>76
> typedefも避けるという流儀はあるからね
それはC++ではないか?Cでは使われまくりだったような。 国際会議で誰も知らない方言を話して良い訳ない。オープンなソースコードは世界中の人が見るんだから。 >>78
多分linuxカーネルの流儀じゃないかな
struct/enum/unionとかの省略を目的としたtypedefは行わない
opaque-type/関数ポインタとかの必然性が無い限り対象は明示するっていう戦略 >>80
> struct/enum/unionとかの省略を目的としたtypedefは行わない
こんなのは当たり前だ。(linuxカーネルに限らず)
そもそも「タイプ数をケチるだけの為に何かする」という文化は最近のWeb系馬鹿言語だけであって、Cにはない。
当然、else if を elif にしたがる奴もいない。
「腕のいい奴のコードは短い」を勘違いしてる馬鹿共がやたら「タイプ数」にこだわってるだけだ。
だいたい、structをタイプしたくなければC++コンパイラ使えば済むし。 ここで聞いていい内容なのかわからないのですが
gccを4.8.1から8.1.0に変えたらwinAPIを使用して図形を表示するプログラムで
図形が表示されずウィンドウだけ表示されるようになってしまった
これは、c言語,gcc,winAPIどれを疑えばいいのでしょうか?
MingW-W64-buildsというところから8.1.0のgccはダウンロードした >>81
なぜ唐突にweb系云々に話が飛ぶのか理解できないのだが、
typedef struct {...} S;
typedef enum {...} E;
void f(S* s, E e);
上のような書き方、結構(昔から)見かける気がするけど >>82
お前の頭、だな
gcc4.8.1で行けるのならそれでやればいい話。
それを8.1.0に変えただけで問題が発生するのなら、当然そこに問題がある。
そしてそもそも詳しいことはそのソースを作った奴に聞け。 というかこれ以外だとtypedefを使うべき所にしか使わないはずなので、
cだろうがc++だろうがtypedefの使用量に差が出るとは思えない
ああ、実は>>78ってc++ならusing使うべきとかそういう話? >>84
> 上のような書き方、結構(昔から)見かける気がするけど
個人的には疑問があるが、おそらく実際はそちらの方が正しいのだろう。
C++で対策された=C言語のそこがウザイと禿が判定した、ということだから。
> なぜ唐突にweb系云々に話が飛ぶのか理解できないのだが、
ググレば分かるが、その辺の言語では「こちらの方が短いから良い」といっているページは結構見かける。
C言語でこれを言っている奴は皆無だ。
>>86
> ああ、実は>>78ってc++ならusing使うべきとかそういう話?
いや、そうじゃない。そちらの取り方で問題ないし、君の typedef の使い方は正しいと思う。
typedefって結局「型に別名を与える」為の物で、
型が自由に定義出来るようになったC++ではほぼ要らないはず、って話。 >>85
そうか...仕様変更、バグ、なにか他にも入れるものがあるとか分かるなら聞きたかったんだが
仕方ない。ありがとう
4.8.1だと古くなってるかなと思って思い切って8.1.0で試してみてるんだけど戻すか Web系言語界隈は条件演算子をif文の簡略表記()だの省略形()だの言ってる池沼も多いからなぁw >>88
まじめにやる気があるのなら、少しずつ上げて切り分けるのは簡単だろ。自分でやれよ。
ここで聞くより早いと思うぜ。 else if の省略形は確かに頂けない
あれはperlからだっけか? #elifはあって、elifがないのは変だが、キーワードを節約するためだから。 >>91
歴史的には多分sh
70は多分python >>90
なるほど、きざんでやってみます
ありがとうございます >>87
あー...もしかして自分の
>struct/enum/unionとかの省略を目的としたtypedefは行わない
これが「型定義時に、キーワードとしてのstructやenum、unionの省略のためだけのtypedefは行わない」
つまりstruct S{...}という形で定義し、明示的にvoid f(struct S* s)などといった形式で取り扱う
...という意味ではなく、
「structやenum、unionといった型について、それら個々の名前(タグ名)を単に省略するためだけのtypedefは行わない」
つまりtypedef struct SS...SS Sというただの省略形式にするtypedefは行わない
と伝わったのかな
それなら書き方が悪かった、申し訳ない >>92
自分もここが引っ掛かったんだよね。
プリプロセッサ向けにはelifキーワードがあるのに
コンパイラ向けにはない。
もしもキーワード数を節約したり実行速度のみを重視する実装なら
プリプロセッサ向けにもelifキーワードはなかった筈。
なのにある,ということはなにかしらタイプ数の節約とか読み易さとかを考慮してるんだろうね。
だからコンパイラ向けにelifキーワード(の紛い物)を追加するというのは何らおかしくないと思うのだが。 そもそもC言語にはelse ifって構文はないよ。
んで、プリプロセッサは#の後をスペースなしの1語にした結果だと思う。 フリーフォーマットだからelse if(...)を自分なりに分かりやすくすれば良いだけ。 >>74
賛成
静的解析はツールだけがすることではなく人力でもすることだ
人力「でも」と言ったが、目的意識を持って判断できるのは人間だけで
こちらが主役であることを、小者でアフォなやつほど忘れる >>99
でも>>75でも言われてるけど
プリプロセッサ命令を効かせてから解析するのが普通なんだから
あんま関係なくね? ■ このスレッドは過去ログ倉庫に格納されています