LINUX.ORG.RU

Что за бред с инициализией переменной????


0

0

Всё пишется на С.
Приведу для начала код:

/**************file1.c***************/

struct netfw_ip_rule{
	struct netfw_ip_rule *prev;
	struct netfw_ip_rule *next;

	char *table;
	char *ip;
};

static struct netfw_ip_rule *from;

int netfw_mod_from(int action, char *table_name, char *arg, struct sk_buff **skb)
{
	switch(action)
	{
		case NETFW_ADD_RULE:
			{
				if(from)/* if (table_name)*//*from->table = table_name*/ printk("from is visible in int netfw_mod_from(...)\n");
			}
			break;
		case NETFW_DEL_RULE:
			break;
		case NETFW_CHK_RULE:
			break;
		default:
			break;
	}
	return 0;
}
...

void netfw_init_base_mod(void)
{
...
	from = kmalloc(sizeof(struct netfw_ip_rule),GFP_DMA);
	from->next = from->prev = from;
	if(from) printk("from is visible in void netfw_init_base_mod(void)\n");
...
}
/************************************/

oid netfw_init_base_mod(void) вызывается из одного файла а 
int netfw_mod_from(...) вызывается из другого сишника.

Так вот а трабла в том, что переменная from инициализированная в 
последней функции и объявленная как глобальная переменная не видна из 
первой функции. А определил это как видно из мессаги которая выводится
из второй функции и не выводится из первой.
Т.е. в логе только мессага

Jul  9 11:24:51 dell kernel: from is visible in void netfw_init_base_mod(void)

и всё а первой функции нет.

Может кто пояснит почему переменная обьявленная как глобальная, видна 
только в фуенкции где она инициализирована?

Пы.Сы. Прбовал обьявить переменную в хидере (т.к. идеи уже кончились) но это
не помогло :(

Заранее спасибо!!!
★★★★★

Если б переменная была не видна, код не скомпилировался б. А в твоём случае все эти строчки будут писаться если указатель ненулевой, после успешного выделения памяти например, или до оного - когда указатель в мусор.

anonymous
()
Ответ на: комментарий от anonymous

Про видимость это я так выразился, просто не знаю как обозвать такое явление. Там стоит if(COND)code, т.е. код выполниться если COND != 0, у меня получается что в одном месте переменная ноль в другом нет, _НО_ переменная одна и она глобальная т.е. в обоих функкциях она должна быть не ноль, но почему то в той функции где она инициализируется она действительно не ноль, в другой функции (та что выше, она вызывается после того как вызвана функция в которой я выделил память) она уже ноль и if не проходит. Вот именно это и не понятно, ведь переменная _ИНИЦИАЛИЗИРОВАНА_ !!!

cyclon ★★★★★
() автор топика

Поробуй так:

int netfw_mod_from(int action, char *table_name, char *arg, struct sk_buff **skb)
{
if(from)
    printk("from is visible in int netfw_mod_from(...)\n");
switch(action)
{
...

stalcker
()
Ответ на: комментарий от stalcker

Я конечно так сделал, но данный кейс отрабатывается точно. Короче тоже самое. О том что там не видно выделенной памяти я узнал по сегфолту в этом кейсе.

cyclon ★★★★★
() автор топика

У тебя функции в разных c файлах, покажи как во втором файле объявляешь from, или ты включаешь один файл в другой?

stalcker
()

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

merlinse
()
Ответ на: комментарий от merlinse

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

Вот поэтому я и стпосил, но может он в file1.c делает
#include"file2.c"

stalcker
()
Ответ на: комментарий от stalcker

Убирание статика ни к чему не приводит, впрочем и как его добавление. Те функции что я написал, находятся в одном файле.

Пы.Сы. прошу не держать меня за ламера :)))

Единственно что находится в разных файлах, так это вызовы двух этих функций, но сначало идёт вызов второй а потом первой функции. Т.е. как и должно быть, сначала инициализия а потом использование переменной.

cyclon ★★★★★
() автор топика
Ответ на: комментарий от cyclon

А зачем ты описываешь глобальную переменную как static? static, применяемый к глобальным объектам, ограничивает их видимость в пределах единицы компиляции (файла), ты точно этого хотел? Попробуй переобъявить from в том файле, где вызывается netfw_mod_from (и где её, как ты говоришь, "не видно") с export.

shumer
()
Ответ на: комментарий от shumer

Я же написал _НЕТ_ТАМ_STATIC'А_, это во первых, во-вторых, все фунции как и эта переменная обьявлены в одном сишном файле!

cyclon ★★★★★
() автор топика
Ответ на: комментарий от cyclon

Опиши структура проекта: какие файлы, где что объявлется, определяется, вызывается. Трудно понять что к чему без этого.

shumer
()
Ответ на: комментарий от shumer

Вообщем решил сделать похожий сишник, на случай если есть где описки. 
Но результат оказался тем же, т.е. глобальная обьект инициализирован 
только в пределах той функции где она непосредственно 
инициализируется. И посему решил таки описать всю структуру проекта. 
Итак начнём..

Общий вид файлов и вызовов.

/*************main.c**************/
#include  "main.h"
#include  "mod.h"
#include  "tab.h"

void set(SOME_ARG)
{
    table = findTab(NAME);
    table->set(ONE_MORE_ARG);
}

setModule(struct table *t)
{
    //добавляет в список
}

setTable(struct module *m)
{
    ///добавляет в список
}

struct table findTab(NAME)
{
    короче ищет нужный table;
    и возвращает указатель;
}

struct module findMod(NAME)
{
    короче ищет нужный module;
    и возвращает указатель;
}

void test()
{
   set(SOME_ARG);
}

void init()
{
   mod_init();
   tab_init();
   test();
}
/*********************************/

/*************main.h**************/
struct table{
    struct table *prev;
    struct table *next;
    ...
    void (* set)(SOME_ARG);
};

struct module{
    struct module *prev;
    struct module *next;
    ...
    void (* mach)(ARG);
};

static struct table tables;
static struct module modules;

void setTable(struct table *t);
void setModule(struct module *m);
/*********************************/

/*************mod.c**************/
#include "main.h"
#include "mod.h"

struct ip{
   struct ip *prev;
   struct ip *next;
   ...
};

struct ip *rule;

mach()
{
   //ВОТ КАК РАЗ ОТ СЮДА И НЕ ВИДНО rule
   //т.е. if(rule) = 0;
}

mod_init()
{
   struct module new = kmalloc(...);
   new->mach = mach;
   setModule(new);

   rule = kmalloc(...);
   rule->prev = rule->next = rule;
   //А ВОТ ЗДЕСЬ ВСЁ ПУЧКОМ
   //т.е. if(rule) != 0;
}
/*********************************/

/*************mod.h**************/

void mod_init();

/*********************************/

/*************tab.c**************/
#include "main.h"
#include "tab.h"

set(ARG)
{
    struct module m = findMod(NAME);
    m->mach(ARG);
}

tab_init()
{
   struct table new = kmalloc(...);
   new->set = set;
   setTable(new);
}
/*********************************/

/*************tab.h**************/

void tab_init();

/*********************************/

Вот такая структура. Вообщем где-то как-то так :)

cyclon ★★★★★
() автор топика
Ответ на: комментарий от cyclon

В приведенном тобой коде не показаны вызовы этих функций, только определения. Где main() ? Предполагаю, что все-таки mach() вызывается раньше mod_init(). Проверь порядок вызовов.

shumer
()
Ответ на: комментарий от cyclon

main.h
....
static struct table tables;
static struct module modules;
....

За ламера тебя, говоришь, держать не надо?
Ну-ну.
Шагом марш книгу по C читать!

Во-первых, про то, как работает include
Во-вторых, про то, где храняться переменные.

У тебя должно быть так:
main.h
...
extern struct table tables;
extern struct module modules;
...

и где-нить в файле main.c:
...
struct table tables;
struct module modules;
...

Предваряя вопрос, почему так работает, а как у тебя - не работает: начни ^@$%#@, наконец читать книжки.

execve
()
Ответ на: комментарий от execve

Млин, вы читаете то что я пишу?!

Вопервых это модуль, разве kmalloc и printk ни о чём не говорят. 
Во-вторых, порядок вызова правелен, что проверено через вывод различных меток с помощью printk. И в третьих, 

....
static struct table tables;
static struct module modules;
.... 

^- это работает и не имеет к вопросу никакого отношения. Поскольку 
обращение к этим структурам идёт через функции которые лежат в одной 
области видимости с этими структурами. Если был бы вопрос про эти
структуры то я бы так и написал, а я даже в примере модуля
обозначил где проблемма. 

Пы.Сы. без обид, учитесь читать :)))

cyclon ★★★★★
() автор топика
Ответ на: комментарий от cyclon

На всякий случай повторю кусок:

/*************mod.c**************/
#include "main.h"
#include "mod.h"

struct ip{
   struct ip *prev;
   struct ip *next;
   ...
};

struct ip *rule;

mach()
{
   //ВОТ КАК РАЗ ОТ СЮДА И НЕ ВИДНО rule
   //т.е. if(rule) = 0;
}

mod_init()
{
   struct module new = kmalloc(...);
   new->mach = mach;
   setModule(new);

   rule = kmalloc(...);
   rule->prev = rule->next = rule;
   //А ВОТ ЗДЕСЬ ВСЁ ПУЧКОМ
   //т.е. if(rule) != 0;
}
/*********************************/

cyclon ★★★★★
() автор топика
Ответ на: комментарий от cyclon

Может я скажу глупость, но не может ли mach() вызываться до того 
как rule проинициализирована?
т.е. откуда-то из недр setModule(new) ?

Vinick ★★
()
Ответ на: комментарий от Vinick

> т.е. откуда-то из недр setModule(new) ?

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

cyclon ★★★★★
() автор топика
Ответ на: комментарий от cyclon

Что, так и не нашел? Ковыряй дебаггером, что еще можно придумать.. Если ничего не найдешь, перекраивай структуру проекта (упрощай) пока не заработает. Да, если найдешь, не забудь написать, самому интересно..

shumer
()

Короче прежде чем пытаться переписать всё заново, поскольку уже идеи кончились, решил проверить (ЧТО БЫ БЫЛО ПОНЯТНО ПОКАЖУ ВСЁ НА ПРИМЕРЕ
КОТОРЫЙ БЫЛ ПРИВЕДЁН), а видно ли вообще из других функций то что 
инициализированно с помощью создания ещё одной функции которую я обьявил 
 в mod.c и mod.h как test_mod(void) и которая вызывается из void init в main.c

void init()
{
   mod_init();

   test_mod();

   tab_init();
   test();
}

заметьте что вызывается сразу после mod_init(), т.е. уже когда rule 
инициализирован. В ней я проверяю через if инициализированность rule. 
И что вы думаете, в ней тоже не видно rule!!! Но если сделать 
инициализацию в mach() и вызвать test_mod() после test()

void init()
{
   mod_init();
   tab_init();
   test();

   test_mod();
}

то в test_mod() rule будет инициализирована!!!! Вообщем ещё покопаюсь,
и если не разберусь, то перенесу инициализацию в mach().

cyclon ★★★★★
() автор топика
Ответ на: комментарий от cyclon

Млять ну надо так было лохануться!!! :(

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

cyclon ★★★★★
() автор топика
Ответ на: комментарий от cyclon

Разные области видимости, потому и не ругался, одна скрыла другую. Думал, о чем-то подобном, но решил, что ты это проверял..

shumer
()
Ответ на: комментарий от shumer

внатуре лоханулся...
это ж надо так переменные называть...
ты хоть помнишь, какая информация в какой переменной?

anonymous
()
Ответ на: комментарий от anonymous

Просто пишется это все уже не один день, в разные файлы добавляются изменения и через день. Просто там всё работало, вот и не заметил, а внимание сосредоточил на другом.

cyclon ★★★★★
() автор топика
Ответ на: комментарий от cyclon

Вообщем огромное спасибо всем кто откликнулся, теперь уже с такой затупкой не столкнусь :)

cyclon ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.