yohhoyの日記

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

C

文字列リテラルは変更できない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)同期プリミティブの利用に関して、不適切な単一スレッド通知処理の使用によるデッドロック(dead lock)発生についてメモ。(条件変数 Step-by-Step入門のおまけ記事) 問題: 1生産者スレッド−1消費者スレッドのとき、mt_slotク…

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

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

条件変数 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_MON…

可変長配列の正式名称

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でも同様。ただし、処理系の振る舞いは下記2種類のうちいずれかとなる。 [A] ヌルポインタ(NULL)…

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準拠システムならばスレッド安全である。(そ…

fputcとputc

C

C標準ライブラリでは、1文字ストリーム出力関数 fputc と putc(char版)、fputwc と putwc(wchar_t版)の2種類が提供される。両関数は機能的に等価。マクロ展開によるトラブル回避のためputc/putwc利用は避け、常にfputc/fputwcを用いること。 putc()は…

main関数のreturn省略

C C++

プログラミング言語C/C++において、main関数のreturn文を省略した場合の振る舞いに関するメモ。まとめ: C99より前では、戻り値が未定義(undefined)とされる。*1 C99以降では省略可能。「return 0;」として扱う。 C++では省略可能。「return 0;」として扱う。…

条件演算子と左辺値の扱いの差

C C++

プログラミング言語C/C++における条件演算子(?:)と左辺値の扱いについてメモ。言語仕様の隅をつつく話題であり、通常はif文を利用するべき。下記コードはCでは未定義動作(undefined behavior)を引き起こすが、C++ではwell-definedであり期待通り動作する(…

長さゼロ on 文字列/メモリ操作関数

C

標準Cライブラリヘッダ string.h, wchar.h で提供される文字列/メモリ操作関数に対し、長さ 0 を指定した時の振る舞いについて。操作対象とする文字列/メモリの “長さ” をとる関数において、該当引数に 0 を指定したときの振る舞いは下記の通り規定される…

ラベル名と識別子名

C C++

プログラミング言語C/C++のラベル(label)名は、他の識別子名(関数名や変数名など)と独立した名前空間((C++のnamespaceとは別物。))を持つ。 void f() { /* foo statement */; std: // OK /* bar statement */; } C++03 6.1/p1より該当箇所を引用。 (snip) …

ヌルポインタの内部表現

C

プログラミング言語Cにおけるヌルポインタ値の内部表現(≒ビット表現)に関して、標準規格では特に規定しておらずその内部表現は非ゼロであっても良い。*1注意:定数値0はヌルポインタ定数として解釈されるが、ここで言う“ヌルポインタの内部表現”とは関係が…

関数パラメータリストと配列型

C C++

C/C++言語における関数パラメータリスト中の配列型に関するメモ。下記の関数f1, f2はどちらの宣言でも同じ関数(同一の型)として扱われる。 void f1(int a[42], const char b[]); void f1(int * a, const char * b); // a = int型へのポインタ型, b = const…

標準入出力とchar/wchar_t型の混在

C C++

C/C++標準ライブラリの標準入出力ストリームにおける char/wchar_t 型混在についてメモ。またはCの printf/wprintf 関数、C++の cout/wcout オブジェクト混在利用に関する話題。まとめ:ある標準入出力ストリームに対する char/wchar_t 入出力操作の混在…

NULL-NULL=?

C C++

C/C++言語におけるヌルポインタ同士の減算に関するメモ。 int *p = NULL, *q = NULL; ptrdiff_t x = (p - q); // x == 0 ? まとめ: C言語仕様上は未定義動作(undefined behavior)。とはいえ、大半の処理系では値0になると予測される(単に経験則)。 C++言…

浮動小数点数比較マクロ

C C++

C99で追加された浮動小数点数比較マクロについてメモ。同機能はC++11においても提供される。比較マクロとそれに対応する比較演算の一覧。組込みの比較演算子では浮動小数点数例外(floating-point exception)が発生する可能性があるが、比較マクロでは決して…

古のK&R C in 2012

2012年現在のC言語コンパイラでもK&R Cソースコードを扱えるか試したのでメモ。*1結論:gccとMSVCはK&R Cソースコードでもコンパイル可能。 /* K&R style C */ int printf(); int add(); main(argc, argv) int argc; char** argv; { printf("1+2=%d\n", add(…