Namespaces
Variants

Other operators

From cppreference.net

他の主要カテゴリに該当しない演算子のコレクション。

演算子 演算子名 説明
( ... ) 関数呼び出し f ( ... ) 関数 f ()を、0個以上の引数で呼び出す
, コンマ演算子 a, b a を評価し、その戻り値を無視して副作用を完了させた後、式 b を評価し、この評価の型と結果を返す
( type ) 型変換 ( type ) a a の型を type にキャストする
? : 条件演算子 a ? b : c a が論理的に真(ゼロに評価されない)の場合、式 b を評価し、そうでない場合は式 c を評価する
sizeof sizeof演算子 sizeof a a のバイト単位のサイズ
_Alignof
(C11以降)
_Alignof演算子 _Alignof ( type ) type に必要なアライメント
typeof typeof演算子 typeof ( a ) a の型

目次

関数呼び出し

関数呼び出し式の形式は以下の通りです

( 引数リスト  (オプション) )

ここで

expression - ポインタから関数型への任意の式( 左辺値変換 後)
argument-list - 任意の完全オブジェクト型の式(カンマ演算子は不可)のカンマ区切りリスト。引数を取らない関数を呼び出す場合は省略可能。

関数呼び出し式の動作は、呼び出される関数のプロトタイプが呼び出し時点で スコープ内 にあるかどうかに依存します。

プロトタイプを持つ関数の呼び出し

1) パラメータの数は引数の数と等しくなければなりません(省略記号パラメータが使用されている場合を除く)。
2) 各パラメータの型は、対応する引数の無修飾型からパラメータの型へ、 代入による暗黙変換 が存在するような型でなければならない。
さらに、 配列型 のすべてのパラメータについて、 static キーワードが [ ] の間に使用されている場合、引数式はパラメータのサイズ式で指定された要素数以上の配列の要素へのポインタを指定しなければならない。
(C99以降)
4) 代入 は、各引数の値を対応する関数パラメータにコピーするために実行され、パラメータ型とその再帰的な要素またはメンバー(存在する場合)の型修飾子は無視されます(注:関数はそのパラメータを変更できますが、それらの変更は引数に影響しません;C関数呼び出しは値渡しのみです)。
5) 関数が実行され、その返す値が関数呼び出し式の値となる(関数がvoidを返す場合、関数呼び出し式はvoid式となる)
void f(char* p, int x) {}
int main(void)
{
    f("abc", 3.14); // array to pointer and float to int conversions
}

プロトタイプ宣言のない関数の呼び出し

2) デフォルト引数プロモーション がすべての引数式に対して実行される。
3) 代入 が実行され、各引数の値が対応する関数パラメータにコピーされる。パラメータ型とその再帰的な要素またはメンバ(存在する場合)の型修飾子は無視される。
4) 関数が実行され、その戻り値が関数呼び出し式の値となる(関数がvoidを返す場合、関数呼び出し式はvoid式となる)
void f(); // no prototype
int main(void)
{
    f(1, 1.0f); // UB unless f is defined to take an int and a double
}
void f(int a, double c) {}

プロトタイプ宣言のない関数呼び出しの動作は、以下の場合に未定義となる:

  • 引数の数がパラメータの数と一致しない場合
  • 引数のプロモート後の型が、パラメータのプロモート後の型と 互換性 がない場合。ただし以下の例外がある:
  • 同じ整数型の符号付きと符号なしバージョンは、引数の値が両方の型で表現可能な場合、互換性があるとみなされる
  • voidへのポインタと(cvr修飾された可能性のある)文字型へのポインタは互換性があるとみなされる
(C23まで)

注記

関数呼び出しの対象となる expression および全ての引数の評価は互いに unsequenced です(ただし、関数本体の実行開始前にはシーケンスポイントが存在します)

(*pf[f1()]) (f2(), f3() + f4()); // f1、f2、f3、f4は任意の順序で呼び出される可能性があります

関数呼び出しは関数へのポインタに対してのみ定義されていますが、 関数からポインタへの暗黙変換 により、関数指示子でも動作します。

int f(void) { return 1; }
int (*pf)(void) = f;
int main(void)
{
    f();    // fをポインタに変換してから呼び出し
    (&f)(); // 関数へのポインタを作成してから呼び出し
    pf();    // 関数を呼び出し
    (*pf)(); // 関数指示子を取得し、ポインタに変換してから呼び出し
    (****f)(); // ポインタに変換、関数を取得、4回繰り返してから呼び出し
    (****pf)(); // こちらも有効
}

未使用の引数を無視する関数(例えば printf など)は、未定義動作を引き起こさないようにするため、プロトタイプがスコープ内にある状態で呼び出す必要があります(このような関数のプロトタイプは必然的に 末尾省略記号 パラメータを使用します)。

現在の標準文書における関数パラメータの準備に関する意味論の記述は欠陥があります。なぜなら、呼び出し時に引数からパラメータへの代入が行われると規定しているため、const修飾されたパラメータやメンバ型を誤って拒否し、多くのプラットフォームで実装不可能なvolatileの意味論を不適切に適用してしまうからです。C11以降の欠陥報告 DR427 はこのような意味論を代入から初期化へ変更することを提案しましたが、欠陥ではないとして閉じられました。

関数呼び出し式において、 expression が完全に識別子で構成されており、その識別子が未宣言である場合、その識別子は以下のように宣言されているかのように動作します:

extern int identifier(); // returns int and has no prototype

したがって、以下の完全なプログラムは有効なC89です:

main()
{
    int n = atoi("123"); // implicitly declares atoi as int atoi()
}
(C99まで)

コンマ演算子

コンマ演算子の式は以下の形式を持ちます

lhs , rhs

ここで

lhs - 任意の式
rhs - 他のカンマ演算子以外の任意の式(言い換えれば、カンマ演算子の 結合性 は左から右)

まず、左オペランドである lhs が評価され、その結果の値は破棄されます。

その後、 シーケンスポイント が発生し、 lhs のすべての副作用が完了します。

その後、右オペランドである rhs が評価され、その結果がカンマ演算子によって non-lvalue として返されます。

注記

lhs の型は void であってもよい(すなわち、 void を返す関数の呼び出しであるか、または cast 式で void に変換された式であってもよい)

C++ではコンマ演算子が左辺値になることがありますが、Cでは決して左辺値になりません

コンマ演算子は構造体を返すことがあります(構造体を返す他の式は複合リテラル、関数呼び出し、代入、条件演算子のみです)

以下のコンテキストでは、カンマ演算子を式の最上位レベルに置くことはできません。カンマが異なる意味を持つためです:

コンマ演算子をそのような文脈で使用する必要がある場合は、括弧で囲む必要があります:

// int n = 2,3; // エラー: コンマは次の宣言子の開始と見なされる
// int a[2] = {1,2,3}; // エラー: 要素数よりも多くの初期化子
int n = (2,3), a[2] = {(1,2),3}; // OK
f(a, (t=3, t+2), c); // OK: 最初にtに3を格納し、次に3つの引数でfを呼び出す

トップレベルのコンマ演算子は配列の境界でも許可されません

// int a[2,3]; // エラー
int a[(2,3)]; // OK、サイズ3のVLA配列(VLAとなる理由:(2,3)は定数式ではないため)

コンマ演算子は、 定数式 では、トップレベルかどうかに関わらず許可されません

// static int n = (1,2); // エラー: 定数式ではカンマ演算子を呼び出せません

キャスト演算子

参照: cast operator

条件演算子

条件演算子の式は以下の形式をとります

条件式 ? 真の場合の式 : 偽の場合の式

ここで

condition - スカラー型の式
expression-true - conditionがゼロと比較して等しくない場合に評価される式
expression-false - conditionがゼロと比較して等しい場合に評価される式

expression-true および expression-false として許可されるのは以下の式のみです

(C23以降)
  • 一方の式がポインタで、もう一方がヌルポインタ定数(例: NULL または nullptr_t (C23以降)
  • 一方の式がオブジェクトへのポインタで、もう一方が(修飾された可能性のある)voidへのポインタである場合
1) まず、 condition を評価します。この評価の後には sequence point があります。
2) condition の結果がゼロと等しくない場合、 expression-true を実行し、それ以外の場合 expression-false を実行する
3) 評価結果から以下のように定義される 共通型 への 変換 を実行する:
1) 式が算術型を持つ場合、共通の型は usual arithmetic conversions 後の型です
2) 式が構造体/共用体型を持つ場合、共通型はその構造体/共用体型となります
3) 両方の式がvoidの場合、条件演算子式全体はvoid式となります
4) 一方がポインタで他方がnullポインタ定数 または nullptr_t (C23以降) の場合、型はそのポインタの型となる
5) 両方がポインタの場合、結果は両方の指し示す型のcvr修飾子を組み合わせた型へのポインタとなる(つまり、一方が const int * で他方が volatile int * の場合、結果は const volatile int * となる)。また、型が異なる場合、指し示す型は 複合型 となる。
6) 一方がvoidへのポインタである場合、結果は結合されたcvr修飾子を持つvoidへのポインタとなる
7) 両方が nullptr_t 型の場合、共通型も nullptr_t となる
(C23以降)
#define ICE(x) (sizeof(*(1 ? ((void*)((x) * 0l)) : (int*)1)))
// xが整数定数式の場合、マクロは以下に展開される
sizeof(*(1 ? NULL : (int *) 1))  // (void *)((x)*0l)) -> NULL
// ポイント(4)に従ってこれはさらに変換され
sizeof(int)
// xが整数定数式でない場合、マクロは以下に展開される
// ポイント(6)に従って
(sizeof(*(void *)(x))           // 不完全型によるエラー

注記

条件演算子は決して lvalue式 にはなりませんが、構造体/共用体型のオブジェクトを返す可能性があります。構造体を返す可能性がある他の式は、 代入 コンマ演算子 関数呼び出し 、および 複合リテラル のみです。

C++では、左辺値式である可能性があることに注意してください。

この演算子と代入の相対的な優先順位の詳細については、 operator precedence を参照してください。

条件演算子は右から左への結合性を持ち、連鎖を可能にします

#include <assert.h>
enum vehicle { bus, airplane, train, car, horse, feet };
enum vehicle choose(char arg)
{
    return arg == 'B' ? bus      :
           arg == 'A' ? airplane :
           arg == 'T' ? train    :
           arg == 'C' ? car      :
           arg == 'H' ? horse    :
                        feet     ;
}
int main(void)
{
    assert(choose('H') == horse && choose('F') == feet);
}

sizeof operator

sizeof演算子 を参照

_Alignof operator

_Alignof演算子 を参照

typeof operators

typeof 演算子 を参照

参考文献

  • C23規格 (ISO/IEC 9899:2024):
  • 6.5.2.2 関数呼び出し (p: 未定)
  • 6.5.3.4 sizeofおよび_Alignof演算子 (p: 未定)
  • 6.5.4 キャスト演算子 (p: 未定)
  • 6.5.15 条件演算子 (p: 未定)
  • 6.5.17 コンマ演算子 (p: 未定)
  • 6.7.3.5 typeof指定子 (p: 115-118)
  • C17規格 (ISO/IEC 9899:2018):
  • 6.5.2.2 関数呼び出し (p: 58-59)
  • 6.5.3.4 sizeofおよび_Alignof演算子 (p: 64-65)
  • 6.5.4 キャスト演算子 (p: 65-66)
  • 6.5.15 条件演算子 (p: 71-72)
  • 6.5.17 コンマ演算子 (p: 75)
  • C11規格 (ISO/IEC 9899:2011):
  • 6.5.2.2 関数呼び出し (p: 81-82)
  • 6.5.3.4 sizeofおよび_Alignof演算子 (p: 90-91)
  • 6.5.4 キャスト演算子 (p: 91)
  • 6.5.15 条件演算子 (p: 100)
  • 6.5.17 コンマ演算子 (p: 105)
  • C99規格 (ISO/IEC 9899:1999):
  • 6.5.2.2 関数呼び出し (p: 71-72)
  • 6.5.3.4 sizeof演算子 (p: 80-81)
  • 6.5.4 キャスト演算子 (p: 81)
  • 6.5.15 条件演算子 (p: 90-91)
  • 6.5.17 コンマ演算子 (p: 94)
  • C89/C90標準 (ISO/IEC 9899:1990):
  • 3.3.2.2 関数呼び出し
  • 3.3.3.4 sizeof演算子
  • 3.3.4 キャスト演算子
  • 3.3.15 条件演算子
  • 3.3.17 コンマ演算子

関連項目

一般的な演算子
代入 インクリメント
デクリメント
算術 論理 比較 メンバー
アクセス
その他

a = b
a + = b
a - = b
a * = b
a / = b
a % = b
a & = b
a | = b
a ^ = b
a <<= b
a >>= b

++ a
-- a
a ++
a --

+ a
- a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

! a
a && b
a || b

a == b
a ! = b
a < b
a > b
a <= b
a >= b

a [ b ]
* a
& a
a - > b
a. b

a ( ... )
a, b
( type ) a
a ? b : c
sizeof


_Alignof
(C11以降)
(C23まで)

alignof
(C23以降)

C++ documentation for Other operators
日本語訳:
C++ documentation for その他の演算子
変更点: - "Other operators" → "その他の演算子" に翻訳 - HTMLタグ、属性、C++固有の用語("C++ documentation")はそのまま保持 - 書式と構造は完全に維持