Kernel/VM探検隊はカーネルや仮想マシンなどを代表とした、低レイヤーな話題でワイワイ盛り上がるマニアックな勉強会です。植山氏は、制作中のリンカである「mold」について発表しました。全2回。前半は、リンカの概要について話しました。 LLVMのリンカ「lld」オリジナルの作者植山類氏:植山類です。今僕が作っているmoldというリンカについて発表します。 今回の発表の概要です。リンカが何かを知っている人はそんなにたくさんいないと思うので、まず説明します。次に、「mold」のポイントは速いことなのですが、速いと何がうれしいのかを説明します。そのあと、どれくらい速いのかを説明した上で、どう実現されているのか、概要を紹介します。詳細になると何時間あっても終わらないので、かなりハイレベルな話をします。 自己紹介のスライドを入れていませんが、僕はリンカを何度か作ったことがあって、LLVMのlldの

発端はuchan_nos氏によるこのツイートでした。 C言語で、本当にメモリの0番地にデータを書きたいときはどうすりゃええの?— うー@技術書典8 Day1う31 BitNOS (@uchan_nos) 2020年2月12日 それに対する私のリプライ:uint8_t *p = 1; p--; *p = v;— hikalium (@hikalium) 2020年2月12日 私はこれで話が終わると思っていたのだが、どうやらそうではなかったらしく、色々な視点からの意見が加わりながら、話は混沌を極めたのでした…。 ということで、ここに私のこのツイートに対しての見解とか、わかったことをまとめておこうと思います。 私のリプライの背景について uchanさんが求める「0番地にデータを書きたい」という課題設定を、私はこのように解釈しました。 C言語において、整数0をポインタに変換すると、それはNULL
マイクロカーネルは浪漫に溢れる非常に作りがいのあるソフトウェアです。この記事は,「マイクロカーネルベースのOSの一から作ってIaaSで動かす」ことを目標に作ったマイクロカーネルベースのOS Resea(りーせあ)の設計と実装について軽くまとめた物です。 ソースコードはGitHubにあります。 マイクロカーネルとはLinuxのようなモノリシックカーネルでは色んな機能がカーネル空間で動きますが,マイクロカーネルではユーザプロセスたちが互いに通信しながらOSを作り上げます。プロセス・スレッド・仮想メモリ管理,プロセス間通信,タイマーといった必要最低限の機能だけをカーネルが担います。デバイスドライバやファイルシステムといった残りの機能は,独立したユーザプロセスとして動きます。たとえデバイスドライバが暴走しても他のコンポーネントを壊すことはないのです。マイクロカーネルは信頼性が高く,疎結合で美しい
C/C++でコーティングしていると、特定のサイズにアライメントされた領域が必要なることがありますよね。ハードウェアに近いところを実装してると「4KiBでアラインせよ」とか普通にありますね。 このようなアライメントされた領域を確保する方法はいくつかありますが、今回は可搬性の高い方法をいくつか紹介します。 posix_memalign 関数 これは名前の通り、POSIX準拠の関数ですので Unix やLinux などほとんどの環境で動作します。プロトタイプ宣言は int posix_memalign(void **memptr, size_t alignment, size_t size); です。 この関数は、引数 size(Byte)の大きさの領域を確保し、引数 memptr の指す先へ領域へのポインタを格納します。その領域は引数 alignment で指定した値でアライメントされていま

とかやると思いますが、このmallocで帰ってくるメモリがどこから来るか答えられる人は居ますか?バッチリ答えられるという人、glibcのソースコードを読んだことある人は帰っていただいて大丈夫です。メモリは天から降ってくる恵みだと思っている人、学校では習った気がするけど実はよく知らないという方はこの記事を読むとよいと思います。 C言語でプログラムを書かないから関係ないという方も一読してみてください。C++でプログラムを書いたとしても、new演算子で動的にメモリを確保する際には内部でmallocが使われています。他の言語で書いている場合でも動的なメモリの確保の際、密かにmallocのお世話になっているのです。少しでもメモリの気持ちがわかることで、メモリに優しいプログラム、メモリ不足でクラッシュしにくいプログラムを書くことができるようになります。 なお、malloc関数はシステムコールではなくラ

まえおき 巷では「プログラマーになりたい人に初学者にとって、ポインタという考え方がわけわかめ」という話がよくあります。 そこでいろいろな人が「ポインタは住所だ」とか「変数がハコで」とか手を変え品を変え分かりやすいように説明してくれています。 それでもなお「ポインタがわかりづらい」という人が後を絶ちません。 もういっそのこと、例え話をやめてド直球で攻めたらいいんじゃないでしょうか。 Hello, Worldより簡単に サンプルコード 以下のコードを考えます。 void main() { int a; int b; int c; a = 1; b = 2; c = a + b; } 「#include <stdio.h>」なんていう謎のオマジナイはこの際ナシです。あんなもの無くたってC言語は成り立ちます。 まぁ見ての通り、どこにも何も出力されませんが。 このプログラムは、「c = a + b」


(訳注:2016/3/2、いただいた翻訳フィードバックをもとに記事を修正いたしました。) (訳注:著者のMattより、「本文中で明言はしていないが、この記事の内容はx86-64 Unix/Linux/POSIXでアプリケーションをプログラミングする場合にフォーカスしている。他のプログラミング領域では、対象とするシステムに応じた(例: 8-bitの組み込みシステム、10年前のコンパイラ、多くの異なるCPUアーキテクチャで動く必要のあるアプリケーション、Win/Linuxでのビルド互換性など)特有のアドバイスが必要」との補足を頂いております。) 以下の文章は2015年の始めに書いたドラフトで、今まで公開していませんでした。私のドラフト用フォルダの中で誰の目も引かなかったため、大部分が書いた時のままです。公開するにあたり、単純に2015年を2016年に変更しました。 必要な修正、改善、苦情があり

タイトルは「C言語 ポインタ完全制覇」。 このページの書籍化とはいえ、内容の大半は書き下ろしですので、 既にWebで読んでおられる方にも決して損はさせません。 詳細はこちらへどうぞ。 「C言語 ポインタ完全制覇(第2版)」書籍情報 「C言語 ポインタ完全制覇」書籍情報(旧版)技術評論社さんによる書籍案内はこちら。 第2版 旧版 修正履歴は、このページの末尾にあります このページについて 全くもって僭越ながら、恐れおおくも偉そうにも、 こんな文書をWWWで公開させていただくことにしました。 この文書は、もともと社内向けの教科書として作成したものです。 私は、一介の文系出身プログラマであり、 特に情報関係の教育を受けたわけでもなく、 プログラミング言語に深い造詣を持っているわけではありません。 この文書にも多くの誤りや、誤解を招く表現があるかと思います。 そのような記述を見付けられた方は、ぜ
概要 C/C++でよく記述する、ダブルクォーテーションで囲まれた文字列を文字列リテラルと呼び、プログラム実行時に利用する文字列を表現するために利用します。文字列リテラルは普段何気なく使っているにもかかわらず、その実装はなかなかに興味深いものです。本稿はそれを記述していきます。 文字列リテラル 文字列リテラルとは C/C++ではダブルクォーテーションで囲まれた文字列を文字列リテラルと呼びます。リテラルとは本質的には定数を表します。(定数として実装されているかは実装系依存です) コード: 文字列リテラル 文字列リテラルはプログラム実行開始時に、メモリ領域中の特殊な領域に文字配列として確保されます。よって領域定義としては char [] に近いものです。ただし我々が普段使っているスタック領域(関数内で変数宣言したときに使う)やヒープ領域(newやmallocで取得する領域)とは違った箇所に領域を
以下、読書感想文としてのポエムである。 21st Century C1(以下 21CC と略)という、いささか変わった本がある。C言語のプログラマの多くが1980年代の知識に固まってしまっているのを打破しようと書かれた本なのだろうと、ざっと自分が1st editionを読んだ感じ2では思っている。C89 aka ANSI Cがいまだに標準だと思っている人3には、おすすめかもしれない。 「Cはパンクロックだ」 21CCでは C is Punk Rock 4 という表現が書籍の最初と最後に出てくる。このパンクロックが何であるかについての議論はしない5。ただ、パンクロックの例えが「シンプルかつ荒削りだけど力強い」言語に対するものであるというのは、個人的なパンクロックへの印象、そしてC言語の特徴をふまえれば良くわかる。 私も気がつけば30年ぐらいC言語で仕事をしていたりする。そして現在の2015年

C初心者が知っておきたいヘッダーファイルとリンクの基礎知識:目指せ! Cプログラマ(終)(1/4 ページ) プログラミング言語の基本となる「C」の正しい文法や作法を身に付ける入門連載です。今回は、ヘッダーファイルとリンクを中心に、翻訳単位、ファイル有効範囲、外部定義と仮定義、外部結合と内部結合、結合と記憶域期間、インライン関数の結合、static、extern、inlineなどについても解説。 C言語の処理を複数のファイルに分けて書くには本入門連載「目指せ! Cプログラマー」では、これまで、C言語の初心者でも分かるようにさまざまな基本文法や基礎構文、標準ライブラリの使い方などを解説してきました。新社会人はもちろん、C言語に入門したいという方もあらためてバックナンバーを読み返してみてください。 連載もいよいよ終盤です。今回は、C言語の処理を複数のファイルに分けて書く方法について解説します。

こんにちは。谷口です。ITエンジニアの転職やプログラミング学習に関する仕事をしている私ですが、学生の頃は文系の学部に所属し、プログラミングには全く触れたことがありませんでした。 新卒の時はそんな状態で、自分に特性があるのかどうかもよく分からないまま、面接をしてくれた人事担当者の「プログラミングは研修を受ければできるようになるから大丈夫」の言葉を信じて、受託開発をしている企業に入社しました。 そして新人研修で生まれて初めてプログラミングに触れ、勉強する中で、一歩進もうとする度につまずき、進んだと思ったら二歩前に覚えたことを忘れ、ということを繰り返しながら、何とか働いてきた時期がありました。 プログラミングのプの字も知らなかった新人の頃にどこでつまずいてきたかを思い出しながら書いてみたいと思います。 ■代表的なつまずきポイント ◆1.Hello Worldの段階からつまずく 研修で最初に勉強


C言語は宣言文が非常に読みにくいことで有名で、後発のGo言語はこれを批判して宣言の構文を変えています。私もずっと読むのが苦手だったのですが、私の頭が悪いのではなく、C言語の仕様がヘン、ということらしい。 今まで飽きるほどこの手の解説は書かれてきてるわけですが、自分なりにまとめないと覚えた気がしないので、あえてまとめておきます。ここに書いてある内容は、「C言語ポインタ完全制覇」に詳しく書いてあります。 型の派生 C言語では、int, char, floatなどの基本型から、配列やポインタを派生していくことができます。対象を並べたものが配列で、対象を指し示すのがポインタです。 配列やポインタからも配列やポインタを派生できるので、派生パターンは無限に存在します。 int int の配列 int の配列 の配列 ... int へのポインタ int へのポインタ へのポインタ ... int への

Linuxカーネル開発者になりたいと思っても、まず何から手をつけたらいいか分からず、始める前から挫折する人も多いだろう。すぐ始められる最初の一歩の例が、筆者の経験を交えて4つ挙げてある。 (これは、CUSECというイベントでの、カーネルは怖くないという話の続き) カーネルプログラミングを始めるにはどうしたらいいか、アドバイスを求めたことがある。その時は、こう回答があった。仕事のためにカーネルを理解する必要がなくても、やってみたらどうだろう?Linuxカーネルメーリングリストに登録してみて、精一杯理解しようと頑張ってみよう。 メインのLinuxカーネルの一部にならないコードを書いているなら、時間の無駄だ。 これは私にとっては、全然、少しも役に立たなかった。そんなわけで、ここでは、あなたなりにOSやLinuxカーネルがどう働くか、楽しみながら理解していくための、いくつかの戦略について書いて
Linuxのスレッドは、洗練された美しい設計です。スレッドは仮想アドレス空間とファイルディスクリプタテーブルを共有するプロセスに過ぎません。プロセスによって生成されたスレッドは、メイン”スレッドの”親プロセスに追加された子プロセスです。これらは同じプロセス管理のシステムコールを通して処理されるので、スレッドに関するシステムコールのセットを分ける必要性を取り除きます。これはファイルディスクリプタと同様に洗練された方法です。 一般的に、UNIX系のシステムではfork()を使ってプロセスを生成します。新しいプロセスは、オリジナルのコピーとして独自のアドレス空間とファイルディスクリプタテーブルを取得します。(Linuxではコピーオンライトを使用して、この部分を効率的に処理します。)しかし、これは非常に高度なスレッドの生成方法なので、Linuxでは別の clone() システムコールを使用します。

Dmitri Gribenko氏によるBlog記事 "I Do Not Know C" より訳出。原文および訳文のライセンスは CC BY-SA 3.0 に従う。 この記事の目的は、皆に(とくにCプログラマに)「C言語分かってなかった」と言わせることです。 C言語の死角は思っているよりも身近にあり、よくある単純なコードですら 未定義動作(undefined behavior) を含む可能性があると示したいと思います。 記事は質問に対する回答の形をとります。全ての例示コードは別々のファイルに分かれていると考えてください。 (訳注:Qiita/Markdown表現の制約から、読中ネタバレ防止のため文章順序を変更しています。前半には質問のみを、後半には質問と回答の対を訳出しました。) 質問編 1.

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
1リリース、障害情報などのサービスのお知らせ
最新の人気エントリーの配信
処理を実行中です
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く