タグ

Cに関するakaneharaのブックマーク (44)

  • 「Cは超高級アセンブラ?」の「未定義動作」に対する逃げ道の探索 - Qiita

    概要 Cは超高級アセンブラ? - Qiita [キータ] yohhoyさんのコメント ここで挙げられているプログラムは、いわゆる「未定義動作」となります。 http://www.jpcert.or.jp/sc-rules/c-exp05-c.html 環境(コンパイラやOS等)によっては出力結果が20になったり18になったり、はたまた実行時クラッシュを引き起こしたりしますが、いずれもこのプログラムとしては「あり得る」実行結果です。 とあったので、逃げ道がないか探しました。 結論は、構造体の実体そのものにはconstをつけず、メンバにconstつければ逃げられるようです EXP05-C. const 修飾をキャストではずさない には、以下のように記述されています。 変数の型にたいするconst修飾をキャストしてはずさないこと。const 修飾をキャストしてはずすと、プログラムが定数値を変更で

    「Cは超高級アセンブラ?」の「未定義動作」に対する逃げ道の探索 - Qiita
  • Cは超高級アセンブラ? - Qiita

    Help us understand the problem. What is going on with this article?

    Cは超高級アセンブラ? - Qiita
  • EXP05-C. const 修飾をキャストではずさない

    EXP05-C. const 修飾をキャストではずさない ポインタ型のオブジェクトに対するconst修飾をキャストしてはずさないこと。const 修飾をキャストして外すと、ポインタによって参照されるオブジェクトをプログラムで変更できるようになり、未定義の動作となる可能性がある。C 標準の附属書 J 「未定義の動作」の 64 を参照すること。 C 標準 [ISO/IEC 9899:2011] の脚注には以下のように記載されている (セクション 6.7.3, para. 4): 処理系は、volatileでないconstオブジェクトを、読み取り専用記憶域に置いてもよい。さらに、処理系はそのアドレスが使われないならば、そのようなオブジェクトに記憶域を割り付けなくてもよい。 違反コード 以下のコード例の remove_spaces() 関数は、引数として文字列へのポインタ str および文字列長

    EXP05-C. const 修飾をキャストではずさない
  • fcloseはリソース解放を失敗しない

    厳密に言うと、fcloseはエラーを返す可能性がある。しかし、それは、通常のプログラマーが考えるような失敗ではない。 。fcloseが失敗した後、プログラマがストリームに対してできることは何もない。 何故か。規格で明確に、fclose呼び出しが成功しようと失敗しようと、渡されたストリームは閉じられ、ストリームに関連付けられているバッファーも解放されることが保証されている。つまり、たとえfclose呼び出しが失敗したとしても、fcloseに渡したストリームは、すでに閉じられているのである。そのストリームに対して行えることは何も無い。 あるいは、無効なストリームを渡したという場合が考えられる。これは、無効なストリームをfcloseに渡したプログラマーの責任である。誰が失敗したかといえば、プログラマーである。fcloseの責任ではない。 まとめ:正しく実装されたfcloseは、リソース解放を絶対

  • MALLOC

    時事ネタ いや、「今、fj.comp.lang.cが熱い!」という話は ちょっと前から聞き及んではいたのですが、 流量が尋常じゃないらしいので、 忙しさもあって読むのを控えていたんですけど、 先日、大筋を拾い読みしてみました。 確かに熱いですねえ。 いったん収束するかなあ、と思ったら、なんかまた泥沼の気配が(^^; fjを読んでない人のために説明すると(って、 私も普段はあんまり読んでないんですが)、 「malloc()で確保した領域は、必ずfree()で解放しなきゃいけないか?」という 話題でして、「exit()する時には、OSが解放してくれるんだから 別にfree()しなくてもいいじゃん」という主張と、 「いや、malloc()には常に対になるfree()があるべきだ」という主張があって、 議論を呼んでいたのでした。 んで、私がどう思うかなんですが、 私は面倒臭がりなので、free()

  • Cでのエラーハンドリング方法 - khondalitのブログ

    かなり久しぶりの更新です。 仕事が忙しかったですし、そのあとはイベント続きや体調を崩したりで色々時間がなかったので...。 結局今年はプライベートで進めているプロジェクトをまだリリース出来ておらず、辛いです。 さて、この記事を読んでつらつらどうやっていたかを書こうかと思います。 Cのエラーハンドリングと例外設計、例外処理のメモ - 百日半狂乱 最近はCはさほど触らないのですが、これは難しい問題ですよね。 そももそも昔からCのコードのかなりの部分がエラーハンドリングのコードになるということは言われていて、コード量が増える原因の1つになってますね。 ラッパー関数 まずはラッパー関数を作成する方法です。 私がよく使うのはmalloc系のラッパーのxmallocです。 これは昔からよく使われるテクニックです。 void *xmalloc(size_t size) { void *tmp; tmp

    Cでのエラーハンドリング方法 - khondalitのブログ
  • C言語で可変長引数をとる関数を、型安全に書く方法

    C言語の可変長引数は、型安全でない(まちがった型の引数を渡してもコンパイルエラーにならない)とされています。これは言語仕様の理解としては正しいのですが、特定の型の引数を任意の個数とる関数に限っては、マクロを使うことで型安全性を確保することができます。 任意の個数のdoubleを引数にとり、その和を返す関数「sumf」を例にあげて説明します。 C言語の可変長引数機構を使ってsumfを定義すると、以下のようになります。 #include <math.h> #include <stdarg.h> #include <stdio.h> static double sumf(double nfirst, ...) { double r = 0, n; va_list args; va_start(args, nfirst); for (n = nfirst; ! isnan(n); n = va_a

  • ハッシュは二分木(ツリー)より速い(ハッシュとツリーの速度比較) - プログラマはサイコロを振らない

    ハッシュは遅いという意見があるようだが、実装や使い方を誤らなければ、基的にツリーよりハッシュの方が速い。 (この記事は以前書いた「ハッシュは当に遅いのか?いや、遅くない(反語)」を簡潔にまとめたものです) ハッシュとツリーの速度を比較した結果が次のグラフだ(ハッシュはパラメータを適切に設定(後述))。挿入、参照(検索)、削除の合計時間を測定した。(横軸は要素数、縦軸は時間、横軸は対数スケール) 「ハッシュは当に速いのか?」の検証 速いはずのハッシュが二分木にはかないません。ハッシュは速いという常識をくつがえす結果となりました。 http://www.s34.co.jp/cpptechdoc/article/hash/:itle=ハッシュは当に速いのか? Googleで「ハッシュ 速い」で検索すると上記のページが一番上に表示される(2008-08-04現在)。しかし、このページに掲載

    ハッシュは二分木(ツリー)より速い(ハッシュとツリーの速度比較) - プログラマはサイコロを振らない
  • Success is a Journey, not a Destination: 全てのCプログラマが未定義な振る舞いについて知っておくべきこと #1/3

    [What Every C Programmer Should Know About Undefined Behavior #1/3 の翻訳です。] LLVMでコンパイルしたコードは、最適化を有効にしているとたまにSIGTRAPシグナルを生成するのはなぜなのか、と聞かれることがある。いろいろ調べたあと、(X86での話だが) Clangは "ud2" インストラクションを生成していたことがわかった。"ud2" は__builtin_trap()が生成するインストラクションと同じものだ。[訳注: #UD例外を発生させる命令。ソフトウェアが#UD例外をハンドルできているかテストするために使われる。つまり、ソースコードが未定義な振る舞いを使っていたから、LLVMはud2インストラクションを生成したのであって、LLVMのバグではない、ということ] こういう問題は幾つかあって、すべて、Cの未定義な振る

  • DOSプロンプト

    フォーマット指定子一覧 フォーマット指定子とは、C言語のprintf()、fprintf()、sprintf()、scanf()、fscanf()、sscanf()などの関数で使用する、 表示形式を指定するための記述子である。 C言語専用と思っていると、MFC(C++)のCStringクラスやjavaFormatterクラス(jdk1.5以降)にも使用されていたりして、 やはりしっかり覚えておかなくては、と思わせられることもある(詳細は異なるが)。 度忘れした際にはここを見ればよいように、よく使うフォーマット指定子をここにまとめておく。 なお、ANSI規格での全貌を知りたいときは、fprintfのリファレンス等を参照のこと。 出力フォーマット指定子 printf(),fprintf(),sprintf()などで使用する指定子である。

  • C言語 Super Technique 講座

    このページは、C言語の中級テクニックを中心に解説する。長らくプログラマをしていると、C言語の面白い使い方例が蓄積している。これらを一挙公開するために、このページを作ったのである。しかし、単にCに留まらず、他の言語の面白い特徴なども紹介していく。 内容的にはかなりヘヴィである。当然のことながら、「ポインタ虎の巻」程度の内容はちゃんと使いこなせることを前提とする。意外な技、落し穴、派手なテクニックなど、内容満載だが、ちゃんとデータ構造とアルゴリズムなども説明できれば良いと思う。(まあ、ぼちぼちやってきいます...) 以下の目次には手引きのために、評価がつけてある。凡例として示す。 レベル その解説で記載されている内容のレベル 有用度 その内容が実際に役に立つものかどうか 邪悪度 その内容が薦める方法が、一般的なコーディング規約の中で「邪悪」とされがちなものであるか否か。関数ポインタの活用(濫用

  • データ型のアラインメントとは何か,なぜ必要なのか?

    以前このサイトとブログに,何度かアラインメントに関する記事を書きました (サイト内関連ページ参照). そのせいか「アラインメント」で検索して来てくれる人が多いので, 過去の記事に加筆修正してこのページを新たに作成しました. 加筆した点は次のとおりです. アラインメントとメモリアクセス回数の関係をわかりやすくするため, (ほんの少し) 図を導入しました. 「データがアラインされていないとメモリアクセス回数が増える」 と言葉で説明しているサイトは多いのですが, 図で示しているところはまだ見たことありません. アラインされていないアドレスにデータを書き込む場合, 読み出しの場合以上にメモリアクセス回数がかかる可能性があることを追記しました. 以前は「複合データ型 (配列,構造体,共用体) のアラインメント」はほとんど自明のことだと思っていたので軽く流していましたが, 意外なことにこれを解説してい

  • 【C++】なぜヘッダと実装はわけるべきなのでしょうか(.hに実装を書くことは邪道か)

    私はC++歴3年の学生趣味プログラマーです。 「C++はなぜヘッダと実装を分けなくてはならないのか/そもそも当に分けなければならないのか」という質問です。 C++といえば、ヘッダー部と実装部を.hファイルと.cppファイルに分けることが一般的とされている言語ですが、 これは同じオブジェクト指向言語のC#やJavaにはない特徴です。 そのせいでC++使いたちは今日もcppファイルとhファイルを行ったり来たりしながらコーディングする羽目になっています。(そしてVS使いはF12とCtrl+-を得意気に連打しています。) 私にとってもそれが当たり前になって久しいですが、 時々C++を学び始めたばかりの後輩から「なぜヘッダファイルに実装を書いてはならないのか」「なぜC++は二度も同じコードを書くことを強いるのか」と質問を受けます。 私はそのたびに「実装の隠蔽化」とか「循環参照の危険が云々」とか「そ

    【C++】なぜヘッダと実装はわけるべきなのでしょうか(.hに実装を書くことは邪道か)
  • Unix v6 の C コンパイラが面白かった話 - 兼雑記

    Unix v6 の C コンパイラをいじってみようと見てたのですが、これがなかなかすごい物体でした。 読んでて、「いやいくらなんでもこんな作りなわけが…」と思って説明文を探して、 http://plan9.bell-labs.com/7thEdMan/v7vol2b.pdf の「A Tour through the UNIX C Compiler」に説明あるよと教えてもらって読んでみたら、当にそんな作りだった、みたいな。 コンパイラの1段目はプリプロセスして構文木的なものをファイルに吐いて終わりです。2段目は構文木を読みつつコード生成していく。 構文木のノードの種類に対して switch してやること決める…的なものが、データドリブンな方法で書かれてます。データを保存するフォーマットは、 JSON とかではなく、時代が時代ですのでアセンブリです。こういうやつ https://github

    Unix v6 の C コンパイラが面白かった話 - 兼雑記
  • C言語でtuple

    のようにして構造体をつかえばいいのですが、必要になるたびにこれをするのはちょっとめんどくさいですよね。 というわけで色々試行錯誤してみたところ、以下のようにしてunionの配列にするというのがそこそこ便利だったので紹介します。 以下は使用例です。 #include <stdio.h> typedef union { void *p; char *s; int i; char c; } tuple_u; typedef tuple_u tuple[2]; int main(int argc, char *argv[]) { tuple t = { { .s = "hoge" }, { .i = 123 } }; printf("%s, %d\n", t[0].s, t[1].i); return 0; }

  • Webエンジニアが組み込みプログラミングをすることになったときに知っておきたかったC言語の知識 - Qiita

    IoTエンジニアになって半年が過ぎたkazuphです。 (IoTって言葉はいつごろまで使えるんですかね(・∀・)?) PerlRubyでWebアプリケーションを書いていたエンジニアが、C言語でゴリゴリ組み込みプログラミングをすることになったときに、どんなことを知っていたかったかなと思い出しながら書いてみたいと思います。 その辺にある普通のC言語の入門書には載ってない知識が中心です。 ちなみにArduinoの例が多いですが、実際にはほとんどの期間を某チップの某SDKを使って開発しました。 わかる方はそれを想像しながらだと面白いかもしれません(・∀・) 半年の半分はiOSアプリ作っていたので、実質3ヶ月くらいの知識だと思ってください。 間違いの指摘など是非々々お待ちしておりますm(_ _)m こんな記事も書いてます。 IoTやるならまず知っておきたいパーツ屋・オンラインショップ IoTアプリ

    Webエンジニアが組み込みプログラミングをすることになったときに知っておきたかったC言語の知識 - Qiita
    akanehara
    akanehara 2015/05/29
  • configureスクリプトとは何なのか

    Home Subscribe configureスクリプトとは何なのか 19 February 2015 おはこんばんちは!! 尾藤 a.k.a. BTO です。 みなさん Unix のパッケージをインストールする時、configureスクリプト実行しますよね。 なんかいっぱいいろんな事してるみたいで便利そうですよね。 でも実際は何をしてるんでしょうね。 configureスクリプトの出力見てますか? エラーが起きたときしか見てない事ないですか? 先日、よく使ってるんだけどよく知らないと思われる configure スクリプトの正体について、オトバンクで勉強会をやりました。 魔法の呪文 ./configure && make && make install よく打っているコマンドだと思いますが、これだけで解決します。 素晴らしいですね!! GNU Autotools configure

    configureスクリプトとは何なのか
  • メモリプール

    CようにGC(ガベージコレクション)を持たない言語ではヒープ領域から確保したメモリの解放はプログラマの責任で行う必要がある。 しかし、実際にCやC++でプログラミングしたことがあるならわかるように確保したメモリを適切なタイミングで 解放するのはとても難しいとまでは言わないまでもあまり簡単なことではない。 単にfreeを呼び出すのを忘れたり、もしくはリストや木のような少し複雑なデータ構造を扱う際に 割り当てられたメモリを適切に解放できずにリークしてしまうようなことは普通に起こりうる。 モダンなOSではプログラム終了後にそのプログラムに割り当てられたメモリをOS側で解放してくれるので、 走らせてすぐ終了するようなプログラムではこのようなメモリリークは特に問題にならないこともあるが、 例えばWebサーバのように常時動き続けるようなソフトウェアでのメモリリークは致命的な問題を引き起こす。 この問題

  • C 言語で echo サーバを作ってみよう (2)

    select によるマルチスレッドサーバ C 言語において select の使い方を説明します。 echo-server-select.c 117: int 118: main(){ 119: fd_set target_fds; 120: fd_set org_target_fds; 121: int sock_optval = 1; 122: int port = 5000; 123: /* リスニングソケットを作成 */ 124: listening_socket = socket(AF_INET, SOCK_STREAM, 0); 125: 126: /* ソケットオプション設定 */ 127: if ( setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR, 128: &sock_optval, sizeof(sock_opt

  • Big Sky :: select(2)の第一引数にディスクリプタの最大値を渡すのは間違い?

    追記 POSIX では明確にソケットの最大値とはうたってはいないものの、Linux の実装を見ても最大値と扱う方が良い様です。また Winsock では select(2) の第一引数は無視されるようです。 C言語でソケットを使うプログラミングを行う際、ソケットディスクリプタがシグナル状態かを調べる方法としてselect(2)があります。 使い方は int r; fd_set rfds; FD_ZERO(&rfds); FD_SET(sock, &rfds); r = select(1, &rfds, NULL, NULL, NULL); といった感じ。ここでselect(2)の第一引数に渡している値は、ディスクリプタ集合rfdsの内、いくつ検証するかを指す値。つまりrfdsに対してFD_ZERO/FD_CLRしてからFD_SETした回数となります。 ちなみに戻り値は、ディスクリプタ集合の

    Big Sky :: select(2)の第一引数にディスクリプタの最大値を渡すのは間違い?