yohhoyの日記

技術的メモをしていきたい日記

C

Is volatile useful with threads?

volatileキーワードはマルチスレッド処理に役立つ?.com(http://isvolatileusefulwiththreads.com/) C http://c.isvolatileusefulwiththreads.com/ C++ http://cxx.isvolatileusefulwiththreads.com/ Java http://java.isvolatileusefulwiththreads.com/ C…

配列有効範囲外を指すポインタ値は存在が許されない

C C++

プログラミング言語C/C++における、配列型とポインタ演算の知られざる*1落とし穴。問題:下記sum_odd関数の実行結果は? int data[5] = { 1, 2, 3, 4, 5 }; // 奇数番目の要素値のみを合計する int sum_odd() { int s = 0; int *endp = data + 5; // 配列末…

Designated Initialization @ C++

C++2a(C++20)で導入予定のDesignated Initialization(指示付きの初期化)ついてメモ。C99での同一言語機能をベースとするが、一部機能制限された形でC++に導入される。 // C++2a(C++20) struct Point { int x, y; }; void f(Point); f({ .x = 100, .y = 50 …

初期化子リスト要素数不足時の初期値

C

プログラミング言語Cにおいて、構造体/配列型変数宣言の初期化子リスト(initializer-list)*1で要素数が足りない場合の初期値について。 ポインタ型の場合、ヌルポインタ(NULL) で初期化される。*2 算術型の場合、(正値または符号無し)値0 で初期化される…

ポインタ型への非NULLアノテーションもどき

C99仕様で拡張された構文を用いて、関数引数としてのポインタ型に非NULLアノテーションを行う方法。正直微妙。 int f1(int *p) { if (p == NULL) return 42; return *p; } int f2(int p[static 1]) { if (p == NULL) return 42; return *p; } Clang 3.5/-O1…

Objective-C atomic属性プロパティとスレッド間同期

LLVM/Objective-Cのatomic属性プロパティが保証する性質、C言語(C11)のAtomic変数アクセスとの比較、およびマルチスレッド処理での利用についてメモ。超要約:Objective-C @property宣言には常にnonatomic属性を指定せよ。atomic属性プロパティは人類には早…

数字から数値への変換: ch - '0'

C C++

プログラミング言語C/C++における、1文字の数字から1桁の整数値へ変換するイディオム ch - '0' について。C/C++言語仕様では、数字の文字コード'0'〜'9'がその並び順で連続かつ隣接すると保証する。このため変換元文字chから数字0の文字コード'0'を減算する…

strncpy関数仕様のナゾ

C

C標準ライブラリが提供するstrncpy関数の仕様について。有限長バッファへ文字列を切り詰めてコピーする処理では、strncpy関数が用いられるケースが多い。strncpy関数の仕様として「コピー元srcの文字列長が指定長BUFSIZE以上のとき、コピー先dest末尾にはNUL…

readdir/readdir_r関数のあれこれ

POSIX環境にて提供されるreaddir, readdir_r関数に関するメモ。まとめ: 事実上スレッドセーフが保証されるreaddir関数を使うこと。将来のPOSIX規格でスレッドセーフ保証が追加予定。 readdir_r関数を利用してはならない。POSIXからも廃止予定であり、GLIBC …

scanf文字列取得と動的メモリ確保

C標準ライブラリscanf関数の書式指定%sにおいて、取得先の文字列バッファを動的確保する機能拡張。 // POSIX準拠システム char *s = NULL; scanf("%ms", &s); // sはmallocで確保される ... free(s); まとめ: 標準C(ISO C):該当機能は存在しない。メモリ領…

ローカル変数アドレス返却とgccの挙動

警告:C/C++言語においてはローカル変数*1はその変数スコープ内(関数やブロック)でのみ有効であり、同変数へのポインタ値をスコープ外に持ち出すと未定義動作(undefined behavior)を引き起こす。本記事の内容は未定義動作に依存しているため、実行環境のOS…

Linuxとビット幅指定整数型

C99標準ヘッダ<stdint.h>で定義されるビット幅指定の整数型と、Linux Standard Base(LSB)によるプロセッサ・アーキテクチャ別の規定。x86(IA-32)とx86-64/AMD64における整数型ビット幅は下表の通り(太字はアーキテクチャでビット幅が異なる整数型)。 型名 IA-32 AMD6</stdint.h>…

可変引数リストと文字列とヌルポインタの特別な関係

C C++

C言語の可変引数リストと文字列(文字型へのポインタ)とヌルポインタの関係についてメモ。下記コードではvoid*型をもつマクロNULLの値*1を、関数f実装ではchar*型として展開するが、両ポインタ型は互換型(compatible type)とみなされない*2。関数呼び出し側…

size_tと値-1

C C++

C/C++言語における符号無し型と負数の扱いについてメモ。値-1をsize_tなどの符号なし整数型*1へ変換代入する場合、同型の最大値となることが保証される。この振る舞いは符号付き整数型の内部ビット表現に依存しない。*2 const size_t nmax = -1; // nmaxはsi…

書式指定%lsとwchar_t型

C C++

C/C++標準ライブラリprintf/wprintf関数ファミリでワイド文字列(wchar_t型)を出力する場合、書式指定には常に%lsを利用する。マルチバイト文字列(char型)に対しては、常に%sを利用する。出力先ストリームのバイト指向/ワイド指向(→id:yohhoy:20120825…

criticalコンストラクトへの名前指定

OpenMPのcriticalコンストラクトには、オプションで名前を指定できる。 int acc = 0; #pragma omp parallel for for (int i = 0; i < 10; i++) { #pragma omp critical (acc) acc += func(i); } OpenMPランタイムによる排他制御では、同じ名前を付与したコー…

文字列リテラル最大長の最低保証

C/C++言語における文字列リテラル(string literal)最大長に対する最低保証について。C言語では文字列長さに関する制約が存在する。*1要約: C90:509文字までは言語仕様にて保証。それ以上は環境限界に従う。 509 = 512バイト − CRLF改行(2) − NUL終端(1) C9…

複合リテラルの有効期間

C

C99で追加された複合リテラル(compound literal)の有効期間についてメモ。 ファイルスコープに記述した場合、静的記憶域期間(static storage duration)を持つ。 ブロックスコープに記述した場合、該当スコープ内でのみ有効となる。 C99 6.5.2.5/p3, 6より引…

C関数ポインタにObjective-Cデリゲートを渡す

関数ポインタ型をとるC言語インタフェースのライブラリに、Objective-C言語のデリゲート(Delegate)を指定する方法。ARC(Automatic Reference Counting)環境を想定。 // XxxLibライブラリ C言語/公開インタフェース // コールバック関数ポインタ型 // nValue:…

Clang警告オプションとメッセージ一覧

LLVM/Clangコンパイラの警告オプション(-Wxxx)と出力メッセージの対応一覧表。Clangソースコードから機械抽出とのこと。 http://fuckingclangwarnings.com/(2021-04-09現在サイト消滅) https://github.com/NSHipster/clangwarnings.com

OpenMP並列forループの中断処理

OpenMPによる並列forループにおいて、該当ループの処理途中で中断する方法について。OpenMPでは並列forループ内からの break は禁止されるため、フラグ変数を用いたループ内処理スキップで代用する。並列リージョンでのフラグ変数アクセスは、全てクリティカ…

printfファミリ書式指定%nの応用例

printf関数ファミリの滅多に使われない書式指定%nを利用したコードの例。本記事の内容はStack Overflowで見つけた質問と回答に基づく。2021-10-11追記:C2x(C23)に向け N2834 にて%nの非推奨化(deprecate)が提案されている。 int n; printf("%s: %nFoo\n", "…

sqrt(dx*dx + dy*dy)とhypot(dx, dy)

C C++

C/C++標準ライブラリで2点間距離 (x1,y1) - (x2,y2) を計算する方法。C99以降またはC++11以降では、sqrt関数の他にhypot関数も利用できる。*1 #include <cmath> // C++98 double dist = std::sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); // C++11以降 do</cmath>…

文字列リテラルは変更できないlvalue

C C++

C/C++言語では、文字列リテラル(string literal)は lvalue に分類される。ただし文字列リテラルの変更は未定義動作(undefined behavior)を引き起こす。文字列リテラル以外のリテラルは rvalue(prvalue) に分類される。(通常の)文字列リテラル型は、C++では…

(抄訳)N4215 memory_order_consumeの利用と実装に向けて[§5-6のみ]

C++ C

元文書:(PDF)N4215 Towards Implementation and Use of memory_order_consume, P.McKenney/T.Riegel/J.Preshingほか, 2014/10/05訳出メモ: 自分自身の理解のために日本語訳を行ったC++メモリモデル/memory_order_consumeに関する提案文書。§5, 6のみ訳出…

条件変数とデッドロック・パズル(解答編)

条件変数(condition variable)同期プリミティブの利用に関して、不適切な単一スレッド通知notify_oneの使用によるデッドロック(dead lock)発生についてメモ。(条件変数 Step-by-Step入門のおまけ記事) 問題: 1生産者スレッド−1消費者スレッドのとき、mt_s…

条件変数とデッドロック・パズル(出題編)

条件変数(condition variable)同期プリミティブの利用に関して、不適切な単一スレッド通知notify_oneの使用によるデッドロック(dead lock)発生についてメモ。(条件変数 Step-by-Step入門のおまけ記事)スレッド間の非同期データ送受信機構mt_slot<T>として*1、</t>…

条件変数 Step-by-Step入門

長いのでこちら→条件変数 Step-by-Step入門 - yohhoyの日記(別館) コード:https://gist.github.com/yohhoy/d305a6c5249c55ed89a3

ビットフィールド幅の上限値

C C++

プログラミング言語C/C++におけるビットフィールド幅上限値の差異についてメモ。C++でも型サイズを超えるビット幅指定は避けるべき。 struct X { int m : 100; // ?? }; C: 指定した型サイズsizeof(int)*CHAR_BITを超えてはならない。 C++: 型サイズを超えた…

記事"AndroidのためのSMP入門"

Android Developers公式にて公開されているマルチスレッドプログラミング入門記事。主にARMアーキテクチャを対象として、ハードウェア・メモリモデルの理論的説明と、Java/C/C++プログラミングでの実践的な留意点に言及している。(題名に反して、Android固…