sergeeff 1 23 сентября, 2010 Опубликовано 23 сентября, 2010 · Жалоба Это для переменных. Неужели по отношению к функциям это имеет такой же смысл? А вы попробуйте! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 23 сентября, 2010 Опубликовано 23 сентября, 2010 · Жалоба Это для переменных. Неужели по отношению к функциям это имеет такой же смысл? Именно такой. Если вынести функцию в h-файл без префикса static и подключить к нескольким с-файлам, линкер будет вопить о множественном определении. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
777777 0 23 сентября, 2010 Опубликовано 23 сентября, 2010 (изменено) · Жалоба Пример. Поддержка 7-сегментного индикатора. Кроме знакогенератора и определения собсна цифр как совокупности сегментов там ничего нет. Предлагаете знакогенератор определять где-то в другом месте, а в хедере описывать только как extern? Я предлагаю определять массив с цифрами в той функции, которая будет ими пользоваться. В памяти программ, естественно. Как-то так: func() { static uint16_t Freq[] PROGMEM = { 19, 7, 2, 1 }; ... При чем тут h-файл - хз. Изменено 23 сентября, 2010 пользователем 777777 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sKWO 0 23 сентября, 2010 Опубликовано 23 сентября, 2010 · Жалоба Я предлагаю определять массив с цифрами в той функции, которая будет ими пользоваться. В памяти программ, естественно. для даного тривиального случая да для большого массива который используется многими функциями в разных с-файлах не получиться - памяти программ может не хватить, ИМХО Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 23 сентября, 2010 Опубликовано 23 сентября, 2010 · Жалоба Это для переменных. Неужели по отношению к функциям это имеет такой же смысл?Отнюдь! static для переменных кроме ограничения области видимости это еще и резервирование памяти (вместо размещения на стеке или в регистрах) и группировка переменных в Z-область данных, которая обнуляется при старте программы до вызова main. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DimaG 0 23 сентября, 2010 Опубликовано 23 сентября, 2010 · Жалоба Спасибо, я уже закончил детский сад Собственно, если Вы потрудитесь переключить вид темы на древовидный. то увидите, что мой ответ мало относится к дате выпускного вашего детсада Он был адресован топикстартеру Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
777777 0 24 сентября, 2010 Опубликовано 24 сентября, 2010 (изменено) · Жалоба Я предлагаю определять массив с цифрами в той функции, которая будет ими пользоваться. В памяти программ, естественно. для даного тривиального случая да для большого массива который используется многими функциями в разных с-файлах не получиться - памяти программ может не хватить, ИМХО А для большого массива который используется многими функциями в разных с-файлах определять (define) массив в h-файле тем более нельзя - тогда будут либо проблемы линкера, либо (если его объявить static) в каждом C-файле будет содержаться отдельный экземпляр этого массива, что увеличит размер памяти. И каждая функция будет работать со своим массивом. Если он только для чтения, то ты этого не заметишь, если же это массив данных (в ОЗУ), то программа работать не будет. ЗЫ. только сейчас заметил: "памяти программ может не хватить" :) Ты знаешь контроллеры, в которых память программ меньше, чем память данных? И поэтому такие массивы ты хранишь в ОЗУ? А позволь спросить, как ты их при этом инициализируешь? Ведь инициализировать их можно только из памяти программ, а если они там поместились, зачем из переписывать в ОЗУ? :) Изменено 24 сентября, 2010 пользователем 777777 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sKWO 0 29 сентября, 2010 Опубликовано 29 сентября, 2010 · Жалоба Ты знаешь контроллеры, в которых память программ меньше, чем память данных? А Вы знаете? Я предлагаю определять массив с цифрами в той функции, которая будет ими пользоваться. В памяти программ, естественно. Как-то так: func() { static uint16_t Freq[] PROGMEM = { 19, 7, 2, 1 }; ... вы будете иметь доступ к массиву Freq из другой функции рассположеной в этом же файле? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 29 сентября, 2010 Опубликовано 29 сентября, 2010 · Жалоба ../utils.c:47: warning: implicit declaration of function 'memset' ../utils.c:47: warning: incompatible implicit declaration of built-in function 'memset' ... Почему, что сотворил компилятор? gcc когда встречает использование функции, которая не была объявлена расценивает это как объявление функции (о чём и говорит варнинг "implicit declaration of function 'memset'") когда на стадии линковки выясняется, что фактическое определение функции не совпадает с "implicit declaration", но количество параметров и их размер (но не тип) совпадают, то компилятор ТАКИ линкует код (и снова делает варнинг). Это оказывается работоспособным. Такое поведение НИКАК не связано со способностью компилятора делать оптимизации. невключение заголовочников не уменьшит код ни на грамм. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
777777 0 29 сентября, 2010 Опубликовано 29 сентября, 2010 · Жалоба А Вы знаете? Нет, поэтому и помещаю константные массивы в память программ, а не данных вы будете иметь доступ к массиву Freq из другой функции рассположеной в этом же файле? Этот массив другим функциям не нужен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sKWO 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 · Жалоба Этот массив другим функциям не нужен. Ну а если будет нужен, то Вы займётесь бездумным тиражированием и места ФЛЭШ может не хватить. Об этом я хотел и сказать. Особенно если массив большой а функций его использующих - много. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
777777 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 (изменено) · Жалоба Ну а если будет нужен, то Вы займётесь бездумным тиражированием и места ФЛЭШ может не хватить. Об этом я хотел и сказать. Особенно если массив большой а функций его использующих - много. Нет, это вы займетесь тиражированием. Если массив объявить static и поместить в h-файл, то в каждом c-файле будет экземпляр этого массива! Чтобы он был один, он должен находиться в одном c-файле (без static), а в остальных c-файлах (или в h-файле который в них включаются) он должен быть объявлен как extern. Я не знаю, ну это же азы. Изменено 30 сентября, 2010 пользователем 777777 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sKWO 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 · Жалоба Если массив объявить static и поместить в h-файл, то в каждом c-файле будет экземпляр этого массива! Спасибо, не знал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 · Жалоба Нет, это вы займетесь тиражированием. Если массив объявить static и поместить в h-файл, то в каждом c-файле будет экземпляр этого массива! Чтобы он был один, он должен находиться в одном c-файле (без static), а в остальных c-файлах (или в h-файле который в них включаются) он должен быть объявлен как extern. Я не знаю, ну это же азы. Это заблуждение. Если статическая переменная не используется в коде, то она выкидывается оптимизатором при уровне оптимизации большем чем -00. пример: // test.c static int something; // проверим, попадёт ли эта переменная в запускаемый файл #include <stdio.h> int main(void){ printf("test\n"); return 0; } gcc -o test.out test.c смотрим что попало в бинарь: > nm test.out 08049f20 d _DYNAMIC 08049ff4 d _GLOBAL_OFFSET_TABLE_ 080484bc R _IO_stdin_used w _Jv_RegisterClasses 08049f10 d __CTOR_END__ 08049f0c d __CTOR_LIST__ 08049f18 D __DTOR_END__ 08049f14 d __DTOR_LIST__ 080484c4 r __FRAME_END__ 08049f1c d __JCR_END__ 08049f1c d __JCR_LIST__ 0804a014 A __bss_start 0804a00c D __data_start 08048470 t __do_global_ctors_aux 08048360 t __do_global_dtors_aux 0804a010 D __dso_handle w __gmon_start__ 0804846a T __i686.get_pc_thunk.bx 08049f0c d __init_array_end 08049f0c d __init_array_start 08048400 T __libc_csu_fini 08048410 T __libc_csu_init U __libc_start_main@@GLIBC_2.0 0804a014 A _edata 0804a020 A _end 0804849c T _fini 080484b8 R _fp_hw 080482b8 T _init 08048330 T _start 0804a014 b completed.7021 0804a00c W data_start 0804a018 b dtor_idx.7023 080483c0 t frame_dummy 080483e4 T main U puts@@GLIBC_2.0 0804a01c b something теперь включаем минимальную оптимизацию: gcc -o test.out -O1 test.c смотрим что попало в бинарь: > nm test.out 08049f20 d _DYNAMIC 08049ff4 d _GLOBAL_OFFSET_TABLE_ 080484ec R _IO_stdin_used w _Jv_RegisterClasses 08049f10 d __CTOR_END__ 08049f0c d __CTOR_LIST__ 08049f18 D __DTOR_END__ 08049f14 d __DTOR_LIST__ 080484f4 r __FRAME_END__ 08049f1c d __JCR_END__ 08049f1c d __JCR_LIST__ 0804a014 A __bss_start 0804a00c D __data_start 080484a0 t __do_global_ctors_aux 08048380 t __do_global_dtors_aux 0804a010 D __dso_handle w __gmon_start__ 0804849a T __i686.get_pc_thunk.bx 08049f0c d __init_array_end 08049f0c d __init_array_start 08048430 T __libc_csu_fini 08048440 T __libc_csu_init U __libc_start_main@@GLIBC_2.0 U __printf_chk@@GLIBC_2.3.4 0804a014 A _edata 0804a01c A _end 080484cc T _fini 080484e8 R _fp_hw 080482dc T _init 08048350 T _start 0804a014 b completed.7021 0804a00c W data_start 0804a018 b dtor_idx.7023 080483e0 t frame_dummy 08048404 T main как видим статическая переменная не попала бинарь так как не используется! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
777777 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 · Жалоба Это заблуждение. Если статическая переменная не используется в коде, то она выкидывается оптимизатором при уровне оптимизации большем чем -00. Речь идет о том, что она используется, просто вы не прочитали эту ветку с начала. Если бы она использовалась в одном файле, то можно было определить ее в этом же файле и вопросов бы не возникало. Если же она требуется в нескольких, то некоторые товарищи считают удобным определить (define) ее в h-файле, а чтобы линкер не ругался на то, что она определена в нескольких C-файлах (если этот h-файл в них включен), предлагают объявить ее static. Линкер ругаться перестает, но при этом создает по экземпляру на каждый C-файл в котором она используется. Что, в общем-то естественно. Если это какой-то константный массив (например, таблица 7-сегментного индикатора) то никаких проблем кроме увеличения памяти не произойдет. Если же это именно переменная в ОЗУ, то работающие с ней функции (разумеется если они из разных файлов) будут фактически работать с разными переменными и одна из них не увидит что записала другая. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться