yohhoyの日記

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

C

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

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固…

パスワードとmemset関数

C言語プログラム上で高機密性情報(パスワード文字列など)を消去するケースで、memset関数の単純利用では機密情報がメモリ上に残存してしまい、セキュリティ上の脆弱性につながる可能性がある。 void secure_operation() { // パスワード文字列を取得 char …

volatile変数とOpenMP flush操作の短い関係

C/C++言語 volatile修飾とOpenMP flush操作の関係についてメモ。要約: OpenMP 2.5以前:volatile変数への読込/書込アクセスは、それぞれ暗黙のOpenMP flush操作を伴う。 OpenMP 3.0以降:volatile変数アクセスはOpenMPメモリモデル(≒Memory Consistency)に…

atomicコンストラクトの制限

OpenMP API仕様バージョンと、C/C++言語向けatomicコンストラクトの制限事項についてメモ。 OpenMP 3.0以前 #pragma omp atomic new-line expression-stmt atomic指示文に続く式 expression-stmt では、スカラ型の左辺値(lvalue)式 x に対する更新操作のみが…

環境依存コード切り替えマクロ

C C++

C/C++プリプロセッサを利用した環境依存コードの切り替え。通常の#ifdef〜#endif方式で切り替えるより見た目が綺麗? unsigned int get_tick_msec() { ENV_windows( return GetTickCount(); ) ENV_linux( struct timespec ts; clock_gettime(CLOCK_MONOTONIC…

可変長配列の正式名称

C99で導入された、およびC++14導入予定*1となっている「可変長配列」の言語仕様上の正式名について。2016-04-02追記:2016年3月のWG21会合にてArray Extension TSは取り下げられた。JTC1/SC22/WG21 (PDF)N4586, EWG Motions 2参照。2013-10-19追記:C++14 Dr…

volatile教、あるいはvolatile狂

本文こちら→volatile教、あるいはvolatile狂 - yohhoyの日記(別館)

atomic変数間のatomicなコピー

C C++

プログラミング言語C/C++が提供するatomic変数*1とそのコピー操作に関するメモ。2個のatomic変数間における “atomicなコピー操作” は提供されない。通常は “atomic変数からの読込(load)”+“atomic変数への格納(store)” で代用すればよい。ただし、下記コード…

malloc(0)の振る舞い

C

C標準ライブラリ提供の malloc関数 に対して、メモリ確保サイズ 0 指定時の振る舞いは処理系定義(implementation defined)。realloc, calloc, aligned_alloc*1でも同様。 2021-09-09追記:次期C2x(C23)標準ライブラリreallocではメモリ確保サイズ 0 の指定は…

atomic型と整数型のサイズ

C C++

プログラミング言語C/C++が標準で提供するatomic型は、必ずしも対応する整数型と同一サイズとは限らない。(とはいえlock-freeなatomic型であれば、ネイティブ命令でatomic操作が内部実装されるハズなので、整数型と同一サイズ/内部表現になると考えられる…

Duff's device

C

プログラミング言語Cにおいて、たまに「メモリ転送処理の最適化実装」もしくは「swtich文の難解な使い方」として紹介されるアルゴリズムの名前。ループ展開(loop unwinding, loop unrolling)最適化の一種。オリジナルコードでは転送先to=メモリマップドレジ…

rand関数とstd::random_shuffle関数テンプレートの関係

C++ C

2014-12-04追記:std::random_shuffle関数テンプレートはC++1z(C++17)にて削除(remove)される。http://isocpp.org/blog/2014/11/updates-to-my-trip-report参照。C++標準ライブラリが提供するstd::random_shuffle関数テンプレート*1では、その内部実装にてC…

Cストリーム入出力関数とスレッド安全性

C標準ライブラリの<stdio.h>ヘッダで提供されるストリーム入出力関数において、複数スレッドから同時に対象ストリーム入出力操作を行ったときの振る舞い(スレッド安全性)に関するメモ。まとめ: C99以前:POSIX準拠システムならばスレッド安全である。(それ以外は処</stdio.h>…