Jump to content

    
dxp

Определение размера массива на этапе компиляции

Recommended Posts

В том-то и дело, что нет. :) Когда вы скормите указатель в ту шаблонную функцию, вы получите ругань компилятора. А в случае макроса код будет молча скомпилирован, но размер будет получен неверный - не длина массива, а sizeof() указателя. В этом и состоит подлость, что закрадывается ошибка, которую компилятор отловить не в силах. Шаблонная функция лишена этого недостатка.

Вы правы. Передал в функцию a_s() указатель, получилась длина 1. И отсутствие элемента array[0] компилятор не беспокоит. Keil не выдает даже предупреждения.

Видимо, это должно подтверждать, что разница между массивами и указателями меньше, чем хотелось бы. :)

P.S. можно даже sizeof(array[1]) использовать, и все равно компилятор не ругается. Можно даже sizeof(array[1000000]).

Share this post


Link to post
Share on other sites
10.09.2012 в 13:02, dxp сказал:

Вопрос чисто по программированию на С/С++.

...

Вопрос. Имеется ли тут хорошее решение на С или С++. И если имеется, то какое?

 

11.09.2012 в 16:09, dxp сказал:

пришло время обнародовать решение, как вчера было обещано.

Обнародованное решение с++. Для си есть решение?

Share this post


Link to post
Share on other sites

Вообще, есть такой код (упрощённо)

asd.c
 

#include asd.h

int array[2] = {1,2};

 

asd.h
 

#include asd.h

extern int array[2];

 

main.c
 

#include asd.h

int qwe = sizeof(array);

void main(void)

{

//code

}

Работает. Но я не хочу явно указывать размер массива array. я хочу как-то так

 

#include asd.h

int array[] = {1,2};

 

 

asd.h
 

#include asd.h

extern int array[];

 

main.c
 

#include asd.h

int qwe = sizeof(array);

void main(void)

{

//code

}

Не компилируется. Error[Pe070]: incomplete type is not allowed. Я понимаю, что на этапе компиляции main.c не известен размер array. Если сделать всё в майне, то работает

main.c
 


int array[] = {1,2};

int qwe = sizeof(array);

void main(void)

{

//code

} 

Есть решение для си, которое определило бы размер массива на этапе компиляции, определённого в другом файле? Может макросами/дефайнами как-то хитро сделать?

 

Share this post


Link to post
Share on other sites
6 минут назад, razrab83 сказал:

Есть решение для си, которое определило бы размер массива на этапе компиляции, определённого в другом файле? Может макросами/дефайнами как-то хитро сделать?

Нет, так не получится, т.к. это разные единицы трансляции и они транслируются независимо друг от друга. Для связи единиц трансляции используют заголовочные файлы, но Вы как раз этого и не хотите.

Share this post


Link to post
Share on other sites
1 час назад, razrab83 сказал:

Есть решение для си, которое определило бы размер массива на этапе компиляции, определённого в другом файле?

asd.h:

int const array[] = {1,2};
#define SIZE_ARRAY (sizeof(array))

 

Share this post


Link to post
Share on other sites

не один вариант не работает.

смотрите в чем проблема -


 

#include asd.h

int qwe = sizeof(array);//вот проблемная строчка

void main(void) { //code }

даже если сделать так

#include asd.h
const int a = 10;
  int qwe = a;//вот проблемная строчка

void main(void) { //code }

Компилятор дает ошибку "expression must have a constant value". Т.е. на этапе компиляции qwe нужно инициализировать константой. Не константной переменной, а константой. Как это сделать - хз.

 

Хорошо.... если так си не умеет... можно препроцесор заставить проверить размер массива?

 

пока сделаю так....

asd.c

 

#include asd.h
  
int array[SIZE_ASD] = {1,2};

 

 

asd.h
 

#define SIZE_ASD	2

extern int array[SIZE_ASD];

 

main.c
 

#include asd.h

int qwe = SIZE_ASD;
//или
int qwe2 = sizeof(array) / sizeof(array[0];
                                  
void main(void)
{

//code

}

Этот вариант не нравиться, т.к. SIZE_ASD может быть равен 100, а тут "int array[SIZE_ASD] = {1,2,...};" в фигурных скобках будет 98 элементов. Два последних не инициализируются. Как прероцессор заставить на этапе компиляции проверить, что кол-во элементов при инициализации равно SIZE_ASD - не придумал. Может ключ какой подсунуть компилятору, чтобы он хотя бы ворнинг дал?

 

Edited by razrab83

Share this post


Link to post
Share on other sites

из приведённого кода ничего не понятно что именно вы там делаете,

вычисление размера должно быть сделано в том же asd.c и вытащено наружу в отдельной константной переменной.

 

Share this post


Link to post
Share on other sites
58 минут назад, _pv сказал:

из приведённого кода ничего не понятно что именно вы там делаете,

вычисление размера должно быть сделано в том же asd.c и вытащено наружу в отдельной константной переменной.

 

что не понятного? вот ваш пример

asd.c:

int array[] = {1,2,3};
const int array_size = sizeof(array)/sizeof(int);

main.c:

#include <stdio.h>

extern int array[];
extern const int array_size;

void main(){
  printf("%d", array_size);
}

Это понятно? теперь посмотрите мой самый первый main.c. Мне нужно создать переменную вне тела маин и инициализировать её размером массива.Т.е ваш маин для меня должен быть таким

 

#include <stdio.h>

extern int array[];
extern const int array_size;

int qwe = array_size;


void main(){
  //printf("%d", array_size); //в коде мне не нужно использовать array_size
  printf("%d", qwe); 
}

Не компилируется. expression must have a constant value

Смысл вытаскивать размер массива с помощью константной переменной, если нужно константое значение?

Edited by razrab83

Share this post


Link to post
Share on other sites
15 minutes ago, razrab83 said:

Не компилируется. expression must have a constant value

да, действительно, глобальную переменную инициализировать сам не хочет, надо отдельно.

 

#include <stdio.h>

extern int array[];
extern const int array_size;

int qwe;

void main(){
  qwe = array_size;
  printf("%d", qwe); 
}

 

Share this post


Link to post
Share on other sites
7 часов назад, Andrew_Q сказал:

_pv привел правильный подход

Ну да. Подход создающий лишний ненужный объект в памяти. Неудобный подход.

 

5 часов назад, razrab83 сказал:

не один вариант не работает.

Да ну? Мой не работает? Не верю!

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.