3

なぜこれが機能するのですか:

#include <sys/types.h>
#include <stdio.h>
#include <stddef.h>

typedef struct x {
    int a;
    int b[128];
} x_t;


int function(int i)
{
  size_t a;

  a = offsetof(x_t, b[i]);

  return a;
}

int main(int argc, char **argv)
{
    printf("%d\n", function(atoi(argv[1])));
}

offsetof の定義を正しく覚えていれば、それはコンパイル時の構造です。'i' を配列インデックスとして使用すると、非定数式になります。コンパイラがコンパイル時に式を評価する方法がわかりません。これがエラーとしてフラグ付けされないのはなぜですか?

4

5 に答える 5

2

C 標準ではこれが機能する必要はありませんが、offsetof(type, member)次のような展開になるため、一部の C 実装では機能する可能性があります。

type t; // Declare an object of type "type".
char *start = (char *) &t; // Find starting address of object.
char *p = (char *) &t->member; // Find address of member.
p - start; // Evaluate offset from start to member.

本質的なロジックを表示するために、上記をパーツに分けました。の実際の実装はoffsetof、おそらく実装依存の機能を使用して異なりますが、中心となるアイデアは、架空または一時的なオブジェクトのアドレスがオブジェクト内のメンバーのアドレスから差し引かれ、これがオフセットになるということです。メンバーに対して機能するように設計されていますが、意図しない効果として、(一部の C 実装では) 構造体の配列の要素に対しても機能します。

メンバーのアドレスを見つけるために使用される構造が配列メンバーの要素のアドレスを見つけるためにも機能し、ポインターの減算が自然な方法で機能するため、これらの要素に対して機能します。

于 2013-10-21T23:12:59.337 に答える