printf

提供: Tommy6
移動: 案内検索

int printf (constant char * restrict format, ...)

実装が定義するストリーム(たとえば stdout)に、format が指定する形式に基づいて続く引数を変換し得られる文字列を出力として書き込みます。引数の数が format が必要とする数に満たないときの振る舞いは未定義です。引数の数が format が必要とする数より多いとき、残る引数は評価はされますが無視されます。この関数は format の終端に達した時点で返ります。実行に成功すると 0 を返し、そうでないときは -1 を返します。

出力の同期

特定のカーネル呼び出しと関連付けられたイベントが完了すると、そのカーネル呼び出しが実行した全ての printf() の出力は、実装定義の出力ストリームにフラッシュされます。clFinishコマンドキューに対して呼び出すと、それ以前にキューに挿入され完了したコマンドが実行した printf の出力でまだ出力されていないものは全て、実装定義の出力ストリームにフラッシュされます。複数のワークアイテムで printf() を同時に実行するとき、どのような順番でデータを書き込むかについての保証はありません。例えば、グローバルID (0,0,1) を持つワークアイテムの出力に、グローバルID (0,0,4) を持つワークアイテムやその他のワークアイテムの出力が混じったとしても、それは正当なものです。

出力形式の指定

The format shall be a character sequence, beginning and ending in its initial shift state. format は0以上の次のディレクティブから成ります: 変換されることなく出力ストリームに複製される通常の文字列(% 以外)と変換に関する指示を行う文字列です。変換指示を行う文字列にあたると、後ろの引数が0以上読み込まれ、適用可能であれば対応する変換指示記述に基づいて引数の変換を行い、結果を出力ストリームに書き込みます。format は constant アドレス空間にあるため、コンパイル時に解析可能でなければならず、プログラム実行時に format 自身を動的に作成することはできません。

それぞれの変換指定子は「%」で始まります。「%」の後ろに以下の文字列が続きます:

  • 変換指示記述の意味を変更する0以上の「フラグ」(順不同)。
  • 最小フィールド幅(オプション)。変換された値の文字数がフィールド幅より少ないと、文字列幅がフィールド幅と同じになるように、文字列の左側(既定。後述する左補正フラグを指定して右側にもできます)にスペースを補充します。フィールド幅には、非負の10進整数を指定します[1]
  • 変換指定子 d, i, o, u, x, X を指定して変換した値の最小桁数、変換指定子 a, A, e, E, f, F を指定して変換した値の小数点以下の桁数、変換指定子 g, G を指定して変換した値の最大上位桁数、変換指定子 s を指定して変換した文字列の最大バイト数を指定する「精度」パラメータ(オプション)。精度パラメータは、「.」とそれに続くオプションの10進整数から成ります。ピリオドのみを指定した場合、精度は0と解釈されます。前述の変換指定子以外と一緒に精度パラメータを指定した時の振る舞いは未定義です。
  • ベクトル指示子(オプション)。
  • 引数のサイズを指定する 「長さ修飾子」。長さ修飾子はベクトル指示子で要求されており、ベクトル型を同時に指定します。ベクトル型間での暗黙的な変換は認められていません。ベクトル指示子がないとき、この指示子はオプションです。
  • 適用する変換の種類を指定する「変換指定子」。

フラグ

-
変換結果をフィールド内で左寄せにします。このフラグを指定していないときは右寄せになります。
+
数値の変換の結果が、常に正もしくは負の符号で始まるようにします。このフラグを指定していないときは、負の値が変換されたときのみ符号で始まります[2]
スペース
数値の変換において、結果の最初の文字が符号でないとき、もしくは結果の文字数が0のとき、結果の先頭にスペースを挿入します。スペース および + フラグを同時に指定すると、スペース フラグは無視されます。
#
結果が「別形式」に変換されます、変換指定子 o では、必要な場合に限り、結果の最初の桁が0になるように表示精度を上げます。値と精度が共に0のときは、結果は単に「0」となります。変換指定子 x, X では、0以外の値の変換結果の先頭に「0x」 (x) 「0X」 (X) が付くようになります。変換指定子 a, A, e, E, f, F, g, G では、浮動小数点数の変換結果に、たとえ続く桁がないとしても、常に小数点が含まれるようになります。通常の浮動少数点数の変換では、続く桁がある場合のみ小数点が表示されます。変換指定子 g, G では、trailing zeros are not removed from the result. その他の変換指定子に対してこのフラグを指定したときの振る舞いは未定義です。
0
変換指定子 d, i, o, u, x, X, a, A, e, E, f, F, g, G では、無限大もしくは NaN の変換を除き、フィールド幅に合う文字数にするために、スペースではなく0を文字列の先頭に挿入します。0 および - フラグを同時に指定すると、0 フラグは無視されます。変換指定子 d, i, o, u, x, X では、精度が指定されていると 0 フラグは無視されます。その他の変換指定子に対してこのフラグを指定したときの振る舞いは未定義です。

ベクトル指示子

vn
続く変換指定子 a, A, e, E, f, F, g, G, d, i, o, u, x, X がベクトル引数に対して適用されることを示します。n はベクトルのサイズを指し、2, 3, 4, 8, 16 のいずれかでなければなりません。ベクトル値は次の一般形式で表示されます:
値1 C 値2 C … C 値n
C は区切り文字です。区切り文字はカンマです。

長さ修飾子

ベクトル指示子を設定していないときの長さ修飾子及びそれぞれが持つ意味は以下の通りです:

hh
この修飾子に続く変換指定子 d, i, o, u, x, X が、char もしくは uchar 型の引数に対して適用されることを示します。引数は整数拡張により昇格することになりますが、出力前に char もしくは uchar に変換されます。
h
この修飾子に続く変換指定子 d, i, o, u, x, X が、short もしくは ushort 型の引数に対して適用されることを示します。引数は整数拡張により昇格することになりますが、出力前に short もしくは ushort に変換されます。
l
この修飾子に続く変換指定子 d, i, o, u, x, X が、long もしくは uslong 型の引数に対して適用されることを示します。長さ修飾子 l は、フルプロファイルでサポートされています。組み込みプロファイルでは、64ビット整数値を利用可能なデバイスでのみサポートされます。

ベクトル指示子を設定しているときの長さ修飾子及びそれぞれが持つ意味は以下の通りです:

hh
この修飾子に続く変換指定子 d, i, o, u, x, X が、charn もしくは ucharn 型の引数に対して適用されることを示します。引数の昇格は行われません。
h
この修飾子に続く変換指定子 d, i, o, u, x, X が、shortn もしくは ushortn 型の引数に対して適用されることを示します。引数の昇格は行われません。あるいは、この修飾子に続く変換指定子 a, A, e, E, f, F, g, G が、halfn 型の引数に対して適用されることを示します[3]
hl
この修飾子は、ベクトル指示子が設定されているときにのみ使用できます。この修飾子に続く変換指定子 d, i, o, u, x, X が、intn もしくは uintn 型の引数に対して適用されることを示します。あるいは、この修飾子に続く変換指定子 a, A, e, E, f, F, g, G が、floatn 型の引数に対して適用されることを示します。
l
この修飾子に続く変換指定子 d, i, o, u, x, X が、longn もしくは ulongn 型の引数に対して適用されることを示します。あるいは、この修飾子に続く変換指定子 a, A, e, E, f, F, g, G が、doublen 型の引数に対して適用されることを示します。長さ修飾子 l は、フルプロファイルでサポートされています。組み込みプロファイルでは、64ビット整数値と倍精度浮動小数点数を利用可能なデバイスでのみサポートされます。

長さ修飾子無しでベクトル指示子を設定したときのふるまいは未定義です。ベクトル指示子及び長さ修飾子が指すベクトルデータ型は、引数の型と一致していなければならず、一致していないときのふるまいは未定義です。

変換指定子

d, i
int, charn, shortn, intn, longn 型の引数を [-]dddd 形式の符号付き10進数に変換します。精度指定により、表示する最小の桁数を制御できます。設定した最小桁数より少ない桁数で値を表現できるときは、先頭に0が付加されます。既定の精度は1です。値0を精度0で変換すると、変換結果が空の文字列になります。
o, u, x, X
uint, ucharn, ushortn, uintn, ulongn 型の引数を dddd 形式の符号無し8進数 (o)、符号無し10進数 (u)、符号無し16進表記 (x, X) に変換します。変換指定子 x では abcdef、変換指定子 X では ABCDEF を変換結果を表す文字として使用します。精度指定により、表示する最小の桁数を制御できます。設定した最小桁数より少ない桁数で値を表現できるときは、先頭に0が付加されます。既定の精度は1です。値0を精度0で変換すると、変換結果が空の文字列になります。
f, F
浮動小数点数である double, halfn, floatn, doublen 型の引数を [-]ddd.ddd 形式の10進表記に変換します。小数点以下の数値の桁数は精度指定と同じになります。精度が指定されていないときは、精度6が既定値になります。精度に0が指定されていてかつ # フラグが指定されていないとき、小数点は表示されません。小数点が表示されているとき、小数点の前には最低でも1桁の数値を表示します。適切な桁数になるよう丸めを行います。double, halfn, floatn, doublen 型の引数のうち値が無限大のものは、[-]inf もしくは [-]infinity という形式に変換されます。どちらの形式かは実装に依存します。double, halfn, floatn, doublen 型の引数のうち値が非数 (NaN) のものは、[-]nan もしくは [-]nan(n-char-sequence) という形式に変換されます。どちらの形式か、また n-char-sequence がどのような意味を持つかは実装依存です。変換指定子 F を指定すると、inf, infinity, nan の代わりに INF, INFINITY, NAN がそれぞれ表示されます[4]
e, E
浮動小数点数である double, halfn, floatn, doublen 型の引数を [-]d.ddddd 形式に変換します。小数点の前には数値が1桁(引数の数値が非零であれば非零になります)、小数点以下には精度指定と同じ桁数の数値が表示されます。精度が指定されていないときは、精度6が既定値になります。精度に0が指定されていてかつ # フラグが指定されていないとき、小数点は表示されません。適切な桁数になるよう丸めを行います。変換指定子 E を指定すると、指数部の始まりを表わす文字 e の代わりに E が表示されます。指数部の桁数は指数値を表示するのに必要な分だけ確保されますが、最低でも2桁は常に表示されます。値が0のとき、指数は0になります。double, halfn, floatn, doublen 型の引数のうち値が無限大もしくは非数 (NaN) のものは、変換指定子 f, F と同様の形式に変換されます。
g, G
浮動小数点数である double, halfn, floatn, doublen 型の引数を変換指定子 f もしくは e と同様(G を指定したときは F もしくは E)の形式に変換します。どちらの形式を採用するかは、変換する値と精度指定に依存します。P を、0以外の精度を指定した時は精度の値、精度を指定してないときは6、精度に0を指定した時は1とする。値を変換指定子 E で変換した時の指数部の値を X とすると、P > X ≥ −4 のとき、値は変換指定子 f, F と同様の形式に精度 P-(X+1) で変換され、そうでないとき値は変換指定子 e, E と同様の形式に精度 P-1 で変換されます。# フラグが指定されていないとき、any trailing zeros are removed from the fractional portion of the result and the decimal-point character is removed if there is no fractional portion remaining. double, halfn, floatn, doublen 型の引数のうち値が無限大もしくは非数 (NaN) のものは、変換指定子 f, F と同様の形式に変換されます。
a, A
浮動小数点数である double, halfn, floatn, doublen 型の引数を [-]0xh.hhhhd 形式に変換します。この形式では、小数点の前に16進表記の値が1桁(引数の値が正規化数でありかつ、他に引数に関して指定がないときは非零になります)あり[5]、小数点のあとには精度指定した値と同じ桁数の16進値が表示されます。精度が指定されていないときは、値を正確に表現するのに必要な桁数分の精度を確保します。精度が0で # フラグが指定されていないとき、小数点は表示されません。変換指定子 g では abcdef を、変換指定子 G では ABCDEF を、16進値を表現するのに用います。変換指定子 A では、変換結果を表現するのに、x, p の代わりに X, P を用います。指数部には最低でも1桁表示され、2のべき乗の指数部を10進表記するのに必要なだけの桁数が確保されます。値が0のとき、指数部は0になります。double, halfn, floatn, doublen 型の引数のうち値が無限大もしくは非数 (NaN) のものは、変換指定子 f, F と同様の形式に変換されます。

注: 変換指定子 e, E, g, G, a, A を指定すると、double 型をサポートしている場合に限り、スカラの float および half 型の引数を double 型に変換します。double 型をサポートしていない場合、変換先は double ではなく float 型になり、half 型を float 型に変換します。

c
int 型の引数を符号無し char 型に変換し、変換結果の文字を書き込みます。
s
引数には文字列リテラルを指定します[6]。文字列リテラルを含む配列中の文字は、ヌル終端文字に達するまで書き込まれます(ヌル文字自体は含まれません)。精度が指定されているとき、その値を最大バイト数として書き込みを行います。精度が指定されていない、あるいは精度の値が配列のサイズより大きいとき、配列にはヌル文字列が含まれている必要があります。
p
引数には void へのポインタを指定します。このポインタは、global, constant, local, private アドレス空間のメモリ領域を指すことができます。ポインタの値を、実装が定義する形式の印刷可能文字列に変換します。
%
「%」を書き込みます。引数の変換は行いません。

変換指定が不適切な時のふるまいは未定義です。各変換指定に対応する引数の方が不適切な時のふるまいは未定義です。

フィールド幅が狭い、あるいは幅が0であるために表示が欠けてしまうということはありません。変換結果がフィールド幅より広いとき、変換結果がおさまるよう、フィールドを拡張します。

変換指定子 a, A では、指定された精度の16進浮動小数点数に値が正しく丸められます。

以下に printf() の例をいくつか示します:

float4  f = (float4)(1.0f, 2.0f, 3.0f, 4.0f);
uchar4 uc = (uchar4)(0xFA, 0xFB, 0xFC, 0xFD);
 
printf("f4 = %2.2v4hlf\n", f);
printf("uc = %#v4hhx\n", uc);

上の2つの printf() の出力結果は以下のようになります:

f4 = 1.00,2.00,3.00,4.00 uc = 0xfa,0xfb,0xfc,0xfd

変換指定子 s の有効な利用例を以下に示します。引数の値は文字列リテラルへのポインタでなければなりません。

kernel void my_kernel( ... ) {
    printf("%s\n", "this is a test string\n");
}

変換指定子 s の不適切な利用例を以下に示します:

kernel void my_kernel(global char *s, ... ) {
    printf("%s\n", s);
 
    constant char *p = "this is a test string\n";
    printf("%s\n", p);
    printf("%s\n", &p[3]);
}

ベクトル指定子と長さ修飾子が指すデータ型と引数の型が一致しておらず、不適切な printf の利用となっている例を以下に示します:

kernel void my_kernel(global char *s, ... ) {
    uint2 ui = (uint2)(0x12345678, 0x87654321);
 
    printf("unsigned short value = (%#v2hx)\n", ui);
    printf("unsigned char value = (%#v2hhx)\n", ui);
}

OpenCL C と C99 の printf の違い

  • 長さ修飾子 l と変換指定子 c, s の組み合わせは OpenCL C ではサポートしていません。
  • 長さ修飾子 ll, j, z, t, L は OpenCL C ではサポートしていません。ただし、予約はされています。
  • 変換指定子 n は OpenCL C ではサポートしていません。ただし、予約はされています。
  • OpenCL C では、ベクトル型の出力のために、ベクトル指定子 vn をオプションとして追加しています。
  • 変換指定子 f, F, e, E, g, G, a, A では、double 型がサポートされている場合にのみ、float 型の引数を double 型に変換します。詳しくは clGetDeviceInfo の CL_DEVICE_DOUBLE_FP_CONFIG に関する解説をご覧ください。double 型がサポートされていないとき、引数は double ではなく float 型に変換されます。
  • 組み込みプロファイルでは、64ビット整数がサポートされている場合にのみ、長さ修飾子 l がサポートされます。
  • OpenCL C では、変換指定子 s に設定できる引数は文字列リテラルのみです。

変更記録

脚注

  1. 0 はフィールド幅ではなくフラグとして解釈されることに注意してください。
  2. 浮動小数点数において、負0および0に丸めた負の値の変換はすべて、結果にマイナス符号を含みます。
  3. 拡張機能 cl_khr_fp16 をサポートしているときのみ。
  4. 無限大および非数値では、-, +, スペースフラグは通常通り作用しますが、# および 0 フラグは何も作用しません。
  5. Binary implementations can choose the hexadecimal digit to the left of the decimal-point character so that subsequent digits align to nibble (4-bit) boundaries.
  6. マルチバイト文字に対して何らかの特別な措置が講じられることはありません。変換指定子 s に対応する引数に文字列リテラルへのポインタを指定していない printf 関数の振る舞いは未定義です。


―――― Version 1.2, The OpenCL Specification より翻訳