Узнайте размер массива в C с помощью макроса - PullRequest
2 голосов
/ 19 сентября 2011

У меня проблемы с пониманием, если этот макрос делает то, что должен. Именно в сторонней dll я упаковываю

#ifdef __cplusplus
#define NULL    0
#else
#define NULL    ((void *)0)
#endif
#define GTO_ARG_SIZE(arg) (long)((arg)==NULL ? 0 : (long)(arg)[0])

Предполагается, что длина аргумента arg в моем случае длинная *. Он просто указывает на long, но макрос также используется, когда arg является массивом longs ...

Насколько я понимаю, он возвращает значение в arg [0], если указатель не равен NULL. Но когда аргумент arg указывает на long, он возвращает значение long, а не размер arg (1) ...

ПОСТАНОВИЛИ:

Как многие из вас сказали, мифическая структура содержит свой размер в качестве первого элемента. Извините, у меня нет документации по dll, поэтому я разобрался только после того, как покопался в коде. Сначала я задавался вопросом, действительно ли я так мало знал о C / C ++. Спасибо всем

Ответы [ 2 ]

12 голосов
/ 19 сентября 2011

Может быть сторонняя DLL предполагает, что массивы представлены таким образом, причем первый элемент содержит длину? Это имело бы смысл, если бы массивы также основывались на 1 и проверялись на границы.

Трудно быть более конкретным, когда вы не даете больше информации о коде.

Более классический макрос для вычисления длины массива:

#define ARRAY_SIZE(x) ((sizeof x) / (sizeof *x))

Обратите внимание, что это работает только для реальных массивов, где объявление массива находится в области видимости. Это, в частности, не работает в C:

size_t array_length(const int *data)
{
  /* Note: this is a negative example: IT DOES NOT WORK. */
  return ARRAY_SIZE(data);
}

int main(void)
{
  int test[4711];

  printf("the test[] array is %zu elements long\n", array_length(test));
  return 0;
}

Выше не будет печатать 4711; размер массива не является частью типа const int *, в который массив затухает при вызове функции. Как правило, это не возможно сделать в C, то есть найти размер массива, который был передан функции, принимающей указатель.

1 голос
/ 19 сентября 2011

Это просто возвращает long, на который указывает arg, или ноль, если указатель равен нулю.

Единственный способ увидеть возвращение длины аргумента arg, это если arg является указателем на структуру (или длинный член структуры), которая представляет длину структуры, в которой она используется, выглядит как длинный выстрел, хотя.

Редактировать - эта мифическая структура, скорее всего, будет массивом с информацией о границах, как говорит раскрутка, чем все остальное.

...