[c] 구조체 배열 끝에 빈 괄호 ‘{}’가 필요합니까?

Linux 커널에서 일부 코드 를 쳤습니다 .

static struct ctl_table ip_ct_sysctl_table[] = {
    {
        .procname   = "ip_conntrack_max",
        .maxlen     = sizeof(int),
        .mode       = 0644,
        .proc_handler   = proc_dointvec,
    },
    // ...
    {
        .procname   = "ip_conntrack_log_invalid",
        .maxlen     = sizeof(unsigned int),
        .mode       = 0644,
        .proc_handler   = proc_dointvec_minmax,
        .extra1     = &log_invalid_proto_min,
        .extra2     = &log_invalid_proto_max,
    },
    { }
};

여기서 구조체 배열은로 끝납니다 { }. 어떤 목적으로 추가 되었습니까?
그건 그렇고,이 코드 위에 약간 의 구조체 배열이 있지만 끝에 빈 괄호가 없습니다.

구조체 배열 끝에 빈 괄호를 언제 사용해야합니까?



답변

이 특별한 변화는의 일부 sysctl을 그물 : 사용하지 않는 바이너리 sysctl을 코드를 제거 의 마지막 요소의 초기화 변화, 에릭 W. Biederman에 의해 커밋 ip_ct_sysctl_table에서 배열을 {0}하는 {}(그리고 수행하는 많은 다른 배열 초기화와 유사한 변경).

{0}패턴은 더 이상하지만 주변에 있었던 것으로 보이고, 모두 {0}또는 {}마지막 요소 초기화가 명시 적으로 언급 (리눅스 소스 코드에서) 일반적입니다 Terminating entry그들의 길이를 모른 채 이러한 배열을 소비 할 수있는 패턴의 존재는 가능성이 있으므로, 0으로 초기화 된 종료 항목을 칠 때 소비를 종료합니다. 예를 들어 sound/aoa/fabrics/snd-aoa-fabric-layout.c0으로 초기화하려는 의도의 유사한 배열에 대해서는 주석에 명시 적으로 언급됩니다.

static struct codec_connection toonie_connections[] = {
  {
      .connected = CC_SPEAKERS | CC_HEADPHONE,
      .codec_bit = 0,
  },
  {} /* terminate array by .connected == 0 */
};

답변

아마도 0으로 끝나는 문자열에 익숙 할 것입니다. ctl_table ip_ct_sysctl_table[]는 0으로 끝나는 배열입니다. 즉 마지막 배열 항목에는 모두 0의 멤버가 있습니다.


답변

구조체 배열 끝에 빈 괄호 ‘{}’가 필요합니까?

C 구문 요구 사항을 충족시키기 위해 “구조 배열의 끝에 빈 괄호 ‘{}'”는 필요 하지 않습니다 .

구조체 배열 끝에 빈 괄호를 언제 사용해야합니까?

코드가 센티넬 값을 원할 때 .

프로그램이 모든 0의 최종 배열 요소를 갖는 것이 때로는 끝을 감지하는 데 유용 합니다. 필요가 배열의 응용 프로그램의 사용으로 제공 ctl_table ip_ct_sysctl_table[]하지 않는 C 언어의 필요성.


답변

배열의 요소 수를 하나씩 늘리기 위해 배열 끝에서 0으로 초기화 된 요소입니다.

이 작은 데모를 고려하십시오.

#include <stdio.h>

struct Test
{
  int x;
  int y;
} arr[] =
{
    {1,2},
    {3,4},
//  {}
};

int main(void) {
    printf("%zu\n", sizeof(arr) / sizeof(arr[0]));
    return 0;
}

배열 초기화 목록 끝에서 arr주석을 제거하면 배열 의 크기 가 변경됩니다 {}.

출력 :

포함 // {}(배열에는 2 요소가 있음)

2

{}(배열은 3 원소를 가지고)

3

추가 설명 :

ip_ct_sysctl_table배열은 여기 한 곳에서 사용된다 :

in->ctl_table = kmemdup(ip_ct_sysctl_table,
                sizeof(ip_ct_sysctl_table),
                GFP_KERNEL);

여분 {}은 총 크기를 증가시킵니다 ip_ct_sysctl_table.


답변