Согласно документации GNU по Arrays of Variable Length можно использовать оператор sizeof для определения размера массива переменной длины, переданного в функцию:
Вы также можете использовать массивы переменной длины в качестве аргументов функций:
struct entry tester (int len, char data[len][len]) { /* … */ }
Длина массива вычисляется один раз при выделении хранилища и запоминается для области действия массива, если вы обращаетесь к нему с помощью
sizeof
.
Однако при попытке использовать этот пример с приведенным ниже полным примером кода оператор sizeof
возвращает размер указателя, а не размер выделенного vla, как ожидается на основе приведенного выше фрагмента кода GNU.
Я понимаю, что передача массивов в C сродни передаче указателя на первый элемент массива, но, поскольку в этом случае мы указываем размер в сигнатуре функции, я ожидаю, что поведение будет имитировать при использовании sizeof
в области видимости где объявлен массив.
Я также понимаю, что могу использовать аргумент len
для определения размера; но для удобства и понимания реализации GNU я все еще думаю, что это интересный (если не важный) вопрос.
Заранее благодарю всех, кто может дать представление об этом!
// file: vla.c
#include <stdio.h>
void foo(int len, char data[len][len]) {
printf("sizeof \"foo\" data: %lu\n", sizeof(data));
}
int main(int argc, char * argv[]) {
char data[argc][argc];
printf("sizeof \"main\" data: %lu\n", sizeof(data));
foo(argc, data);
}
Составлено с использованием:
gcc vla.c -o vla -std=c11
Вызывается с использованием:
./vla 2 3 4 5
Вывод:
sizeof "main" data: 25
sizeof "foo" data: 8
Анализ:
Размер main
data
имеет смысл; argc
равно 5, поэтому это (5 * 5 = 25) байтовый 2D-массив.
Ожидалось, что размер foo
data
также будет равен 25, но вместо этого он соответствует размеру указателя. По-видимому, компилятор не использует тот факт, что он знает размер data
в пределах foo
, так как это часть сигнатуры функции.
"%zu"
сsize_t
-->printf("%zu\n", sizeof(...));
- person chux - Reinstate Monica   schedule 03.08.2018