関数指定子と実際の呼び出しとは何ですか?

2020-06-02 c function arguments language-lawyer c99

C99標準によると:

関数指定子、実際の引数、および実際の引数内の部分式の評価の順序は指定されていませんが、実際の呼び出しの前にシーケンスポイントがあります。

関数指定子と実際の呼び出しとは何かを誰かが明確に説明できますか?そしてそれらの違いは何ですか?

Answers

私は、関数指定子は、呼び出す関数プログラムに指示するものであることを前提としています。これは、関数名または式の結果として関数ポインターになる可能性があります。

編集:

次に、関数ポインターの例を示します。

// Two random functions
int foo(int i);
int bar(int i);

// define a function pointer type
typedef int (* func)(int)

// Array of functions

func a[] = {foo, bar}


// calling bar(123)
// (a[1]) is an expression that evaluates to a pointer to `bar`

(a[1])(123);

関数指定子とは何ですか?


関数指定子は、関数型を持つ式です。 sizeof演算子、または66)または単項&演算子のオペランドである場合を除き、「関数の戻り値の型」の関数指定子は、「関数の戻り値の型へのポインタ」の型を持つ式に変換されます。

66)この変換は行われないため、sizeof演算子のオペランドは関数指定子のままで、6.5.3.4の制約に違反します。

出典:C18、§6.3.2.1/ 4-「左辺値、配列、関数指定子」


関数指定子は、特定の機能を識別し、評価されたとき、その機能を指定する式です。

int tip (int);

tip (関数の名前)は、たとえば関数指定子です。

または例:

#include <stdio.h>

int tip (int a) {
    return a;
}

int main (void) {

    int (**foo)(int);

    int (*bar[5])(int);

    bar[0] = &tip;

    foo = &bar;

    printf("%d", (**foo)(4));
}

int foo - (**foo)(4) -を返す関数へのポインターへのポインターは、関数tip関数指定子です。


関数呼び出しとは何ですか?

関数呼び出しは、実際には、 tip(4);ような関数の呼び出しにすぎませんtip(4);

関数指定子は、関数型を持つ式です。つまり、 func(a,b);関数を呼び出す場合、 funcは関数指定子です。

(このような関数指定子は、式に存在する場合、通常、配列が最初の要素へのポインターに減衰するように、関数へのポインターに「減衰」します。)

「実際の呼び出し前のシーケンスポイント」の意味は、関数が呼び出される前に、すべてのオペランドが完全に評価(実行)される必要があることです。 func(a(), b())がある場合a()またはb()が最初に実行されるかどうかは指定されていませんが、 funcが呼び出される前に両方が確実に実行されることがわかっています。

たとえばa()funcでも使用されるグローバル変数を変更したfunc 、その変数へのアクセスは明確に定義された順序でfuncられるため、問題ありません。

Related