реклама на сайте
подробности

 
 
> warning: implicit declaration of function 'memset', почему лишь warning и почему все работает?
Kris2007
сообщение Sep 22 2010, 12:39
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 75
Регистрация: 15-03-07
Пользователь №: 26 193



Правлю чужой код. AVR-GCC, Atmega128
При компиляции выдает море warning-ов на memset, memcpy и.т.п.
Проблему ли в том что нет #include "string.h".

Например:
../utils.c:47: warning: implicit declaration of function 'memset'
../utils.c:47: warning: incompatible implicit declaration of built-in function 'memset'


Но! Стало любопытно, ведь устройства с прошивкой продаются и вроде работают)
Почему, что сотворил компилятор?
Go to the top of the page
 
+Quote Post
3 страниц V   1 2 3 >  
Start new topic
Ответов (1 - 42)
Сергей Борщ
сообщение Sep 22 2010, 12:44
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Kris2007 @ Sep 22 2010, 15:39) *
Почему, что сотворил компилятор?
При известных на этапе компиляции параметрах он генерит встроенные оптимальные (под конкретные параметры) тела функций вместо вызова библиотек. В противном случае споткнулся бы линкер.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Kris2007
сообщение Sep 23 2010, 05:50
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 75
Регистрация: 15-03-07
Пользователь №: 26 193



Хм т.е. все сделано правильно??
И #include "string.h" не стоит добавлять?

Сообщение отредактировал Kris2007 - Sep 23 2010, 05:51
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 23 2010, 06:01
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Kris2007 @ Sep 23 2010, 08:50) *
И #include "string.h" не стоит добавлять?
Не каждого, переходящего на красный свет сбивает машина. Стоит всегда переходить на красный свет?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
vacvvn
сообщение Sep 23 2010, 06:05
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 17-09-10
Пользователь №: 59 547



Цитата(Сергей Борщ @ Sep 22 2010, 16:44) *
При известных на этапе компиляции параметрах он генерит встроенные оптимальные (под конкретные параметры) тела функций вместо вызова библиотек. В противном случае споткнулся бы линкер.

выходит, этот трюк можно использовать для снижения объема кода(если кроме простых memset, memcpy и т д, функций не зовешь)? Не включаешь #include "string.h" и библиотека не занимает места?
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 23 2010, 06:18
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(vacvvn @ Sep 23 2010, 10:05) *
выходит, этот трюк можно использовать для снижения объема кода(если кроме простых memset, memcpy и т д, функций не зовешь)? Не включаешь #include "string.h" и библиотека не занимает места?

А она и так не занимает места. Не думаешь ли ты, что включение какого-то h-файла может что-то добавить к твоему коду? В них хранятся лишь декларации, необходимые компилятору, которые не порождают ни код, ни переменных.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 23 2010, 09:42
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(vacvvn @ Sep 23 2010, 09:05) *
Не включаешь #include "string.h" и библиотека не занимает места?
Возможно я неясно выразился: Включать string.h, конечно, нужно. Просто в некоторых тривиальных случаях компилятор может вместо вызова библиотечной функции вставить прямо в код ее оптимизированную под конкретный случай версию. А если случай нетривиальный (один из параметров - переменная и ее значение неизвестно на этапе компиляции) он вызовет библиотечную функцию.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Dima_G
сообщение Sep 23 2010, 10:05
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699



Советую ознакомиться с
http://ru.wikipedia.org/wiki/%D0%9F%D1%80%...%86%D0%B8%D0%B8

А вообще - ИМХО это бадстайл (функции без прототипа)

Цитата(777777 @ Sep 23 2010, 13:18) *
А она и так не занимает места. Не думаешь ли ты, что включение какого-то h-файла может что-то добавить к твоему коду? В них хранятся лишь декларации, необходимые компилятору, которые не порождают ни код, ни переменных.

Некоторые талантливые программисты могут вставлять в заголовочный файл декларации переменных. biggrin.gif
В таком случае, естественно размер кода будет увеличен
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Sep 23 2010, 10:36
Сообщение #9


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(Dima_G @ Sep 23 2010, 14:05) *
Некоторые талантливые программисты могут вставлять в заголовочный файл декларации переменных. biggrin.gif
В таком случае, естественно размер кода будет увеличен

Я вставляю реализацию функций static inline.
Что имеете против?


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Dima_G
сообщение Sep 23 2010, 10:49
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699



Цитата(MrYuran @ Sep 23 2010, 17:36) *
Я вставляю реализацию функций static inline.
Что имеете против?

функция != переменная
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 23 2010, 11:08
Сообщение #11


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(Сергей Борщ @ Sep 23 2010, 13:42) *
Возможно я неясно выразился: Включать string.h, конечно, нужно. Просто в некоторых тривиальных случаях компилятор может вместо вызова библиотечной функции вставить прямо в код ее оптимизированную под конкретный случай версию. А если случай нетривиальный (один из параметров - переменная и ее значение неизвестно на этапе компиляции) он вызовет библиотечную функцию.

Я извиняюсь, но параметры - практически всегда переменные, но это не препятствие для встраивания тела функции в код. Может memset не самый удачный пример из-за того, что память обычно заполняют какой-то константой, но вот функцию abs() глупо вызывать, передавая ей в качестве параметра константу, согласись. Тем не менее она ведет себя так же - компилятор о ней занет даже без прототипа и встраивает ее тело прямо в код.

Цитата(Dima_G @ Sep 23 2010, 14:05) *
Советую ознакомиться с
http://ru.wikipedia.org/wiki/%D0%9F%D1%80%...%86%D0%B8%D0%B8


Спасибо, я уже закончил детский сад

Цитата(Dima_G @ Sep 23 2010, 14:05) *
Некоторые талантливые программисты могут вставлять в заголовочный файл декларации переменных. biggrin.gif
В таком случае, естественно размер кода будет увеличен

От деклараций (declaration) переменных ни код, ни озу не увеличится. он может увеличиться от определений (definition) переменных или функций. Но это, действительно могут делать только очень талантливые программисты, потому что стоит этот h-файл включить в два c-файла, как линкер выдаст ошибку о том, что в программе имеются несколько переменных с одинаковым именем.

Цитата(MrYuran @ Sep 23 2010, 14:36) *
Я вставляю реализацию функций static inline.
Что имеете против?

Инлайновые функции с точки зрения компилятора являются declaration. Однако, если вы присвоете ее адрес какому-нибудь указателю на функцию, то она станет обычной функцией со всеми вытекающими отсюда последствиями.

ЗЫ. static имеет много значений в C в зависимости от контекста, а что он означает применительно к функции? Я полагаю имеется в виду pure-С?
Go to the top of the page
 
+Quote Post
rezident
сообщение Sep 23 2010, 11:14
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(777777 @ Sep 23 2010, 17:08) *
потому что стоит этот h-файл включить в два c-файла, как линкер выдаст ошибку о том, что в программе имеются несколько переменных с одинаковым именем.
Если они объявлены как static, то промолчит, проглотит и не поперхнется.
Цитата(777777 @ Sep 23 2010, 17:08) *
ЗЫ. static имеет много значений в C в зависимости от контекста, а что он означает применительно к функции?
static применительно к функции? - ограничивает ее область видимости вроде как.
Go to the top of the page
 
+Quote Post
sKWO
сообщение Sep 23 2010, 11:15
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530



Цитата(777777 @ Sep 23 2010, 14:08) *
ЗЫ. static имеет много значений в C в зависимости от контекста, а что он означает применительно к функции? Я полагаю имеется в виду pure-С?

static - как по мне : ограничение видимости в пределах файла


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 23 2010, 11:18
Сообщение #14


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(sKWO @ Sep 23 2010, 15:15) *
static - как по мне : ограничение видимости в пределах файла

Это для переменных. Неужели по отношению к функциям это имеет такой же смысл?
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Sep 23 2010, 11:22
Сообщение #15


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Dima_G @ Sep 23 2010, 14:05) *
Некоторые талантливые программисты могут вставлять в заголовочный файл декларации переменных. biggrin.gif

Пример. Поддержка 7-сегментного индикатора. Кроме знакогенератора и определения собсна цифр как совокупности сегментов там ничего нет. Предлагаете знакогенератор определять где-то в другом месте, а в хедере описывать только как extern? biggrin.gif
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Sep 23 2010, 11:22
Сообщение #16


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(777777 @ Sep 23 2010, 14:18) *
Это для переменных. Неужели по отношению к функциям это имеет такой же смысл?


А вы попробуйте!
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Sep 23 2010, 11:25
Сообщение #17


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(777777 @ Sep 23 2010, 15:18) *
Это для переменных. Неужели по отношению к функциям это имеет такой же смысл?

Именно такой.
Если вынести функцию в h-файл без префикса static и подключить к нескольким с-файлам, линкер будет вопить о множественном определении.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 23 2010, 11:25
Сообщение #18


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(_Pasha @ Sep 23 2010, 15:22) *
Пример. Поддержка 7-сегментного индикатора. Кроме знакогенератора и определения собсна цифр как совокупности сегментов там ничего нет. Предлагаете знакогенератор определять где-то в другом месте, а в хедере описывать только как extern? biggrin.gif

Я предлагаю определять массив с цифрами в той функции, которая будет ими пользоваться. В памяти программ, естественно. Как-то так:
Код
func()
    {
    static uint16_t Freq[] PROGMEM = { 19, 7, 2, 1 };
    ...

При чем тут h-файл - хз.

Сообщение отредактировал 777777 - Sep 23 2010, 11:30
Go to the top of the page
 
+Quote Post
sKWO
сообщение Sep 23 2010, 11:57
Сообщение #19


Местный
***

Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530



Цитата(777777 @ Sep 23 2010, 14:25) *
Я предлагаю определять массив с цифрами в той функции, которая будет ими пользоваться. В памяти программ, естественно.

для даного тривиального случая да
для большого массива который используется многими функциями в разных с-файлах не получиться - памяти программ может не хватить, ИМХО


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
rezident
сообщение Sep 23 2010, 13:33
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(777777 @ Sep 23 2010, 17:18) *
Это для переменных. Неужели по отношению к функциям это имеет такой же смысл?
Отнюдь! static для переменных кроме ограничения области видимости это еще и резервирование памяти (вместо размещения на стеке или в регистрах) и группировка переменных в Z-область данных, которая обнуляется при старте программы до вызова main.
Go to the top of the page
 
+Quote Post
Dima_G
сообщение Sep 23 2010, 15:32
Сообщение #21


Местный
***

Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699



Цитата(777777 @ Sep 23 2010, 18:08) *
Спасибо, я уже закончил детский сад

Собственно, если Вы потрудитесь переключить вид темы на древовидный. то увидите, что мой ответ мало относится к дате выпускного вашего детсада biggrin.gif
Он был адресован топикстартеру
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 24 2010, 05:30
Сообщение #22


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(sKWO @ Sep 23 2010, 15:57) *
Цитата
Я предлагаю определять массив с цифрами в той функции, которая будет ими пользоваться. В памяти программ, естественно.

для даного тривиального случая да
для большого массива который используется многими функциями в разных с-файлах не получиться - памяти программ может не хватить, ИМХО

А для большого массива который используется многими функциями в разных с-файлах определять (define) массив в h-файле тем более нельзя - тогда будут либо проблемы линкера, либо (если его объявить static) в каждом C-файле будет содержаться отдельный экземпляр этого массива, что увеличит размер памяти. И каждая функция будет работать со своим массивом. Если он только для чтения, то ты этого не заметишь, если же это массив данных (в ОЗУ), то программа работать не будет.

ЗЫ. только сейчас заметил: "памяти программ может не хватить" smile.gif Ты знаешь контроллеры, в которых память программ меньше, чем память данных? И поэтому такие массивы ты хранишь в ОЗУ? А позволь спросить, как ты их при этом инициализируешь? Ведь инициализировать их можно только из памяти программ, а если они там поместились, зачем из переписывать в ОЗУ? smile.gif

Сообщение отредактировал 777777 - Sep 24 2010, 05:39
Go to the top of the page
 
+Quote Post
sKWO
сообщение Sep 29 2010, 05:23
Сообщение #23


Местный
***

Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530



Цитата(777777 @ Sep 24 2010, 08:30) *
Ты знаешь контроллеры, в которых память программ меньше, чем память данных?

А Вы знаете?

Цитата(777777 @ Sep 23 2010, 14:25) *
Я предлагаю определять массив с цифрами в той функции, которая будет ими пользоваться. В памяти программ, естественно. Как-то так:
Код
func()
    {
    static uint16_t Freq[] PROGMEM = { 19, 7, 2, 1 };
    ...

вы будете иметь доступ к массиву Freq из другой функции рассположеной в этом же файле?


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
Petka
сообщение Sep 29 2010, 10:00
Сообщение #24


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(Kris2007 @ Sep 22 2010, 16:39) *
../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", но количество параметров и их размер (но не тип) совпадают, то компилятор ТАКИ линкует код (и снова делает варнинг). Это оказывается работоспособным. Такое поведение НИКАК не связано со способностью компилятора делать оптимизации. невключение заголовочников не уменьшит код ни на грамм.
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 29 2010, 17:01
Сообщение #25


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(sKWO @ Sep 29 2010, 09:23) *
А Вы знаете?

Нет, поэтому и помещаю константные массивы в память программ, а не данных
Цитата(sKWO @ Sep 29 2010, 09:23) *
вы будете иметь доступ к массиву Freq из другой функции рассположеной в этом же файле?

Этот массив другим функциям не нужен.
Go to the top of the page
 
+Quote Post
sKWO
сообщение Sep 30 2010, 05:54
Сообщение #26


Местный
***

Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530



Цитата(777777 @ Sep 29 2010, 20:01) *
Этот массив другим функциям не нужен.

Ну а если будет нужен, то Вы займётесь бездумным тиражированием и места ФЛЭШ может не хватить. Об этом я хотел и сказать. Особенно если массив большой а функций его использующих - много.


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 30 2010, 06:12
Сообщение #27


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(sKWO @ Sep 30 2010, 09:54) *
Ну а если будет нужен, то Вы займётесь бездумным тиражированием и места ФЛЭШ может не хватить. Об этом я хотел и сказать. Особенно если массив большой а функций его использующих - много.

Нет, это вы займетесь тиражированием. Если массив объявить static и поместить в h-файл, то в каждом c-файле будет экземпляр этого массива! Чтобы он был один, он должен находиться в одном c-файле (без static), а в остальных c-файлах (или в h-файле который в них включаются) он должен быть объявлен как extern. Я не знаю, ну это же азы.

Сообщение отредактировал 777777 - Sep 30 2010, 06:41
Go to the top of the page
 
+Quote Post
sKWO
сообщение Sep 30 2010, 07:15
Сообщение #28


Местный
***

Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530



Цитата(777777 @ Sep 30 2010, 09:12) *
Если массив объявить static и поместить в h-файл, то в каждом c-файле будет экземпляр этого массива!

Спасибо, не знал.


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
Petka
сообщение Sep 30 2010, 08:04
Сообщение #29


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(777777 @ Sep 30 2010, 10:12) *
Нет, это вы займетесь тиражированием. Если массив объявить 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


как видим статическая переменная не попала бинарь так как не используется!

Go to the top of the page
 
+Quote Post
777777
сообщение Sep 30 2010, 10:38
Сообщение #30


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(Petka @ Sep 30 2010, 12:04) *
Это заблуждение.
Если статическая переменная не используется в коде, то она выкидывается оптимизатором при уровне оптимизации большем чем -00.

Речь идет о том, что она используется, просто вы не прочитали эту ветку с начала.
Если бы она использовалась в одном файле, то можно было определить ее в этом же файле и вопросов бы не возникало. Если же она требуется в нескольких, то некоторые товарищи считают удобным определить (define) ее в h-файле, а чтобы линкер не ругался на то, что она определена в нескольких C-файлах (если этот h-файл в них включен), предлагают объявить ее static. Линкер ругаться перестает, но при этом создает по экземпляру на каждый C-файл в котором она используется. Что, в общем-то естественно. Если это какой-то константный массив (например, таблица 7-сегментного индикатора) то никаких проблем кроме увеличения памяти не произойдет. Если же это именно переменная в ОЗУ, то работающие с ней функции (разумеется если они из разных файлов) будут фактически работать с разными переменными и одна из них не увидит что записала другая.
Go to the top of the page
 
+Quote Post
Juray
сообщение Sep 30 2010, 12:30
Сообщение #31


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 19-03-06
Из: Йошкар-Ола
Пользователь №: 15 388



У меня почему-то линкер не ругался на глобальные переменные (не static), определённые (не объявленные!) в одном заголовочнике, на который куча файлов ссылается. (Да, быдлокод - это я сейчас понимаю, но переделывать уже поздно - "работает - не трогай".)

А вот на попытку сделать глобальной константу (const) - таки ругается. (Это я тогда еще не знал о progmem).

Сообщение отредактировал Juray - Sep 30 2010, 12:59
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Sep 30 2010, 12:59
Сообщение #32


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(Juray @ Sep 30 2010, 15:30) *
А вот на попытку сделать глобальной константу (const) - таки ругается.

С или С++?
И примерчик приведите.
Go to the top of the page
 
+Quote Post
Juray
сообщение Sep 30 2010, 13:14
Сообщение #33


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 19-03-06
Из: Йошкар-Ола
Пользователь №: 15 388



Чистый С. gcc - WinAVR 20050214.

файл global.h:
Код
#ifndef GLOBAL_H
#define GLOBAL_H
...
U16 d_status; //слово текущего статуса
...
#endif //GLOBAL_H


файл check.с:
Код
#include "global.h"
...
Set_bit(d_status,num_bit);
...


файл ins.с:
Код
#include "global.h"
...
Clr_bit(d_status,num_bit);
...


файл outs.с:
Код
#include "global.h"
...
if (bit_is_set(d_status,num_bit)) {
...
};
...


Вот такой изврат... blush.gif
И ведь работает... Только грабли с непрозрачностью потоков данных - во весь рост. Но это уже другая тема.
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Sep 30 2010, 13:20
Сообщение #34


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Странно, что работает.
Грамотнее было бы U16 d_status; определить в файле global.c, а в файле global.h обьявить как extern U16 d_status;
И никакого изврата.
Go to the top of the page
 
+Quote Post
Juray
сообщение Sep 30 2010, 13:51
Сообщение #35


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 19-03-06
Из: Йошкар-Ола
Пользователь №: 15 388



Да вот сам удивляюсь, читая эту ветку.
Что грамотнее - знаю. Говорю же - быдлокод. Вам год версии WinAVR ничего не говорит? Это пять лет назад было - я не знал ни о extern, ни о progmem, только начинал кодить на C, до того на асме для 51-х писал, да на всяких дельфях и фокспро.

Сообщение отредактировал Juray - Sep 30 2010, 13:54
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 30 2010, 15:24
Сообщение #36


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(Juray @ Sep 30 2010, 17:51) *
Вам год версии WinAVR ничего не говорит? Это пять лет назад было

Ты думаешь что в той версии было можно а сейчас нет? А поскольку сейчас той версии ни у кого нет, то придется верить на слово? Я в это не верю - если одна переменная будет объявлена в нескольких объектных файлах, то линкер не может не ругаться. Просто потому, что он не сможет эти переменные разместить. Может твой h-файл включался только в один C-файл и тогда это прокатывало.
Go to the top of the page
 
+Quote Post
rezident
сообщение Sep 30 2010, 15:39
Сообщение #37


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Возможно та версия WinAVR не применяла раздельную компиляцию файлов. Тогда все понятно. На самом деле хедер был включен лишь один раз. Остальные два блокировались препроцессором (#ifndef GLOBAL_H ... #endif).
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 30 2010, 15:58
Сообщение #38


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(rezident @ Sep 30 2010, 19:39) *
Возможно та версия WinAVR не применяла раздельную компиляцию файлов. Тогда все понятно. На самом деле хедер был включен лишь один раз. Остальные два блокировались препроцессором (#ifndef GLOBAL_H ... #endif).

То есть в C-файл включались не только хедеры, но и остальные C-файлы? Неужели WinAVR был таким примитивным? smile.gif
Go to the top of the page
 
+Quote Post
rezident
сообщение Sep 30 2010, 16:03
Сообщение #39


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(777777 @ Sep 30 2010, 21:58) *
То есть в C-файл включались не только хедеры, но и остальные C-файлы? Неужели WinAVR был таким примитивным? smile.gif
Не знаю, я только предположение высказал laughing.gif
Go to the top of the page
 
+Quote Post
Juray
сообщение Oct 1 2010, 11:56
Сообщение #40


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 19-03-06
Из: Йошкар-Ола
Пользователь №: 15 388



Цитата(777777 @ Sep 30 2010, 19:24) *
Ты думаешь что в той версии было можно а сейчас нет?

А полностью абзац прочитать? Я имел в виду, что это было давно, и в таком стиле я уже не пишу.

Цитата(777777 @ Sep 30 2010, 19:24) *
А поскольку сейчас той версии ни у кого нет, то придется верить на слово? Я в это не верю

А я не верю, что ни у кого нет.
И можно проверить в более свежей версии.
Сейчас вот накидал тестовый проектик в 20090313 - работает, ни одного варнинга.

Прикладываю проект вместе с lst и map, а также скриншоты прогона в эмуляторе.
Прикрепленный файл  test.zip ( 5.25 килобайт ) Кол-во скачиваний: 105

Data: 1 bytes (0.1% Full)
(.data + .bss + .noinit)
Build succeeded with 0 Warnings...


Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение

Go to the top of the page
 
+Quote Post
777777
сообщение Oct 1 2010, 16:36
Сообщение #41


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(Juray @ Oct 1 2010, 15:56) *
Сейчас вот накидал тестовый проектик в 20090313 - работает, ни одного варнинга.

Забавно. Те же файлы подсунутые в Visual Studio 2008 выдали ошибку:

1>module.obj : error LNK2005: "char global_var" (?global_var@@3DA) already defined in test.obj
1>C:\Users\SWW\Documents\Visual Studio 2008\Projects\test\Debug\test.exe : fatal error LNK1169: one or more multiply defined symbols found

И еще кто-то говорит о стандартах и переносимости... Интересно, а что скажет IAR, кто-нибудь проверит?
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Oct 2 2010, 08:29
Сообщение #42


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Цитата(Juray @ Oct 1 2010, 15:56) *
Сейчас вот накидал тестовый проектик в 20090313 - работает, ни одного варнинга.

А предупреждения включены? Их вывод лучше в makefile задавать.
IMHO: лучше включить все, ну, кроме некоторых rolleyes.gif , чтобы потом не было грусно при отладке.



--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
Juray
сообщение Oct 2 2010, 08:44
Сообщение #43


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 19-03-06
Из: Йошкар-Ола
Пользователь №: 15 388



Предупреждения - по умолчанию. Этого недостаточно?
И ведь дело не в предупреждениях - по прогону явно же видно, что отовсюду ссылка идет на одну и ту же переменную, да и memory usage при компиляции отчиталось - "1 bytes". (если сделать переменную static - получаем "Data: 2 bytes" ).

Интересно бы проверить в "большом" gcc.

Кстати, вот если в global.h вставить
Код
const char glob_const = 3;

- вываливается ошибка "multiple definition of `glob_const'". Соответственно "Build failed with 1 errors and 0 warnings..."

Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th August 2025 - 18:44
Рейтинг@Mail.ru


Страница сгенерированна за 0.01805 секунд с 7
ELECTRONIX ©2004-2016