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 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему: топик перемещен в архив.