JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
Oracle Solaris Studio 12.2: C ユーザーガイド
search filter icon
search icon

ドキュメントの情報

はじめに

1.  C コンパイラの紹介

2.  C コンパイラ実装に固有の情報

2.1 定数

2.1.1 整数定数

2.1.2 文字定数

2.2 リンカースコープ指示子

2.3 スレッドローカルな記憶領域指示子

2.4 浮動小数点 (非標準モード)

2.5 値としてのラベル

2.6 long long データ型

2.6.1 long long データ型の入出力

2.6.2 通常の算術変換

2.7 Switch 文内の Case 範囲

2.8 表明 (assertion)

2.9 サポートされる属性

2.10 警告とエラー

2.11 プラグマ

2.11.1 align

2.11.2 c99

2.11.3 does_not_read_global_data

2.11.4 does_not_return

2.11.5 does_not_write_global_data

2.11.6 error_messages

2.11.7 fini

2.11.8 hdrstop

2.11.9 ident

2.11.10 init

2.11.11 inline

2.11.12 int_to_unsigned

2.11.13 MP serial_loop

2.11.14 MP serial_loop_nested

2.11.15 MP taskloop

2.11.16 nomemorydepend

2.11.17 no_side_effect

2.11.18 opt

2.11.19 pack

2.11.20 pipeloop

2.11.21 rarely_called

2.11.22 redefine_extname

2.11.23 returns_new_memory

2.11.24 unknown_control_flow

2.11.25 unroll

2.11.26 warn_missing_parameter_info

2.11.27 weak

2.12 事前に定義されている名前

2.13 errno の値の保持

2.14 拡張機能

2.14.1 _Restrict キーワード

2.14.2 _ _asm キーワード

2.14.3 __inline__inline__

2.14.4 __builtin_constant_p()

2.14.5 __FUNCTION____PRETTY_FUNCTION__

2.15 環境変数

2.15.1 OMP_DYNAMIC

2.15.2 OMP_NESTED

2.15.3 OMP_NUM_THREADS

2.15.4 OMP_SCHEDULE

2.15.5 PARALLEL

2.15.6 SUN_PROFDATA

2.15.7 SUN_PROFDATA_DIR

2.15.8 SUNW_MP_THR_IDLE

2.15.9 TMPDIR

2.16 インクルードファイルを指定する方法

2.16.1 -I- オプションによる検索アルゴリズムの変更

2.16.1.1 警告

2.17 フリースタンディング環境でのコンパイル

3.  C コードの並列化

4.  lint ソースコード検査プログラム

5.  型に基づく別名解析

6.  ISO C への移行

7.  64 ビット環境に対応するアプリケーションへの変換

8.  cscope: 対話的な C プログラムの検査

A.  機能別コンパイラオプション

B.  C コンパイラオプションリファレンス

C.  ISO/IEC C 99 の処理系定義の動作

D.  C99 でサポートされている機能

E.  ISO/IEC C90 の処理系定義の動作

F.  ISO C データ表現

G.  パフォーマンスチューニング

H.  K&R Solaris Studio C と Solaris Studio ISO C の違い

索引

2.5 値としてのラベル

C コンパイラは、計算型 goto 文として知られる C の拡張機能を認識します。計算型 goto 文を使用すると、実行時に分岐先を判別することができます。次のように演算子 '&&' を使用して、ラベルのアドレスを取得し、void * 型のポインタに割り当てることができます。

void *ptr;
...
ptr = &&label1;

あとに続く goto 文は、ptr により label1 に分岐できます。

goto *ptr;

ptr は実行時に計算されるため、ptr は有効範囲内にある任意のラベルのアドレスを取得でき、goto 文はこのアドレスに分岐することができます。

ジャンプテーブルを実装するには、計算型 goto 文を次の方法で使用します。

static void *ptrarray[] = { &&label1, &&label2, &&label3 };

これで、次のようにインデックスを指定して配列要素を選択できます。

goto *ptrarray[i];

ラベルのアドレスは、現在の関数スコープからしか計算できません。現在の関数以外のラベルについてアドレスを取得しようとすると、予測できない結果になります。

ジャンプテーブルは switch 文と同様の働きをしますが、両者にはいくつかの相違点があり、ジャンプテーブルではプログラムフローの追跡がより困難になる可能性があります。顕著な相違点は、switch 文のジャンプ先は必ず予約語から順方向にあることです。計算型 goto 文を使用してジャンプテーブルを実装すると、順方向と反対方向の両方に分岐することができます。

#include <stdio.h>
void foo()
{
  void *ptr;

  ptr = &&label1;

  goto *ptr;

  printf("Failed!\n");
  return;

  label1:
  printf("Passed!\n");
  return;
}

int main(void)
{
  void *ptr;

  ptr = &&label1;

  goto *ptr;

  printf("Failed!\n");
  return 0;

  label1:
  foo();
  return 0;
}

次の例では、プログラムフローの制御にジャンプテーブルを使用しています。

#include <stdio.h>

int main(void)
{
  int i = 0;
  static void * ptr[3]={&&label1, &&label2, &&label3};

  goto *ptr[i];

  label1:
  printf("label1\n");
  return 0;

  label2:
  printf("label2\n");
  return 0;

  label3:
  printf("label3\n");
  return 0;
}

%example: a.out
%example: label1

また、計算型 goto 文は、スレッド化されたコードのインタプリタとしても使用されます。高速ディスパッチを行うために、インタプリタ関数の範囲内にあるラベルアドレスを、スレッド化されたコードに格納することができます。