информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
За кого нас держат?Атака на Internet
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Google заблокировала 2 с лишним... 
 Бэкдор в xz/liblzma, предназначенный... 
 Три миллиона электронных замков... 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / beginners
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Господа, будьте снисходительны, не бросайтесь сразу штрафовать за, как вам кажется, глупые вопросы - beginners на то и beginners.
Потому что надо знать как работает компилятор (не Urix-like) 14.06.03 10:23  Число просмотров: 1151
Автор: Ktirf <Æ Rusakov> Статус: Elderman
Отредактировано 14.06.03 10:24  Количество правок: 1
<"чистая" ссылка>
Компилятор проходит через единицы компиляции совершенно независимо! Инстанцировать переменную, определенную в хедере, в одной единице компиляции (сиречь .c/.cpp-файле) и не сделать этого в другой единице компиляции он в принципе не может, потому что не знает о существовании более чем одной единицы компиляции. Об этом знает линкер, но линкер не может добавлять или удалять такой код, он только связывает отдельные объектные файлы.
Определение и объявление: это две большие разницы.
<beginners>
Вопрос про структуры в C/C++ 12.06.03 00:05  
Автор: dzen Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Пусть дана некая структура, описанная в файле 1.c. Вопрос: как получить доступ к ее полям из файла 2.c? Пробовал объявить ее в 2.с как extern, но что-то не помогает. Или руки кривые у меня :)
Объясните пожалста что тут к чему :))
Вопрос про структуры в C/C++ 12.06.03 00:43  
Автор: dl <Dmitry Leonov>
Отредактировано 12.06.03 00:57  Количество правок: 1
<"чистая" ссылка>
> Пусть дана некая структура, описанная в файле 1.c. Вопрос:
> как получить доступ к ее полям из файла 2.c? Пробовал
> объявить ее в 2.с как extern, но что-то не помогает. Или
> руки кривые у меня :)
> Объясните пожалста что тут к чему :))

Повторить описание. А еще лучше, описать ее внутри 1.h и включить 1.h в оба c-файла. Поскольку компилятор работает на уровне отдельных файлов, он ничего не знает о полях структуры, описанных в соседнем файле. Extern же лишь говорит о том, что не надо здесь и сейчас резервировать место под данную переменную, и означает обещание программиста, что она будет определена где-то еще. Нарушит обещание - получит ошибку линкера.
Вопрос про структуры в C/C++ 12.06.03 01:13  
Автор: dzen Статус: Незарегистрированный пользователь
<"чистая" ссылка>
> Повторить описание. А еще лучше, описать ее внутри 1.h и
> включить 1.h в оба c-файла. Поскольку компилятор работает
> на уровне отдельных файлов, он ничего не знает о полях
> структуры, описанных в соседнем файле. Extern же лишь
> говорит о том, что не надо здесь и сейчас резервировать
> место под данную переменную, и означает обещание
> программиста, что она будет определена где-то еще. Нарушит
> обещание - получит ошибку линкера.

А не значит ли это, что в двух с-файлах будет ДВЕ структуры с разными значениями в этих полях? Мне-то нужна одна структура (некий общий объект), к которой можно обращаться из 2-х файлов и читать/изменять эти поля.
С переменными, например, проходит все номально. Если она где-то определена, то сделай ее extern в другом файле - и ты имеешь к ней доступ (ну или через указатели, что проще).
Вопрос про структуры в C/C++ 12.06.03 01:30  
Автор: dl <Dmitry Leonov>
<"чистая" ссылка>
> А не значит ли это, что в двух с-файлах будет ДВЕ структуры
> с разными значениями в этих полях? Мне-то нужна одна
> структура (некий общий объект), к которой можно обращаться
> из 2-х файлов и читать/изменять эти поля.
> С переменными, например, проходит все номально. Если она
> где-то определена, то сделай ее extern в другом файле - и
> ты имеешь к ней доступ (ну или через указатели, что проще).

Структура - это не объект, это задание типа будущего объекта, описание того, из чего будет состоять переменная этого типа, когда она будет создана. Можно наобъявлять хоть миллион структур, в скомпилированный код они никаким образом не попадут, пока не будут созданы переменные. Естественно, стоит следить за одинаковым описанием одних и тех же структур в разных файлах, именно для этого и используются .h-файлы.
Вопрос про структуры в C/C++ 12.06.03 01:56  
Автор: dzen Статус: Незарегистрированный пользователь
<"чистая" ссылка>
> Структура - это не объект, это задание типа будущего
> объекта, описание того, из чего будет состоять переменная
> этого типа, когда она будет создана. Можно наобъявлять хоть
> миллион структур, в скомпилированный код они никаким
> образом не попадут, пока не будут созданы переменные.
> Естественно, стоит следить за одинаковым описанием одних и
> тех же структур в разных файлах, именно для этого и
> используются .h-файлы.

Так, стоп... давай на примерах :) Допустим есть у меня такая структура:
struct s{
int a;
int b;
};

И я создаю общую переменную, которую я хочу использовать из тех 2-х файлов:
struct s new_s;

И все это определено в неком .h файле. Я подключаю его и к 1.с и к 2.с => оба файла видят эту переменную (new_s). Потом я вызываю функцию f параметром которой должна быть эта структура (т.е. чтобы в функции я мог менять значения ее полей ... как я понимаю, параметром должна быть ссылка):
void f(struct new_s* tmp)
{
;
}

Но что-то все равно не получается (компилятор отказывается принимать такой параметр функции ... ).
Блин. Что-то я совсем запутался :)
Вопрос про структуры в C/C++ 12.06.03 02:12  
Автор: dl <Dmitry Leonov>
<"чистая" ссылка>
> И все это определено в неком .h файле. Я подключаю его и к
> 1.с и к 2.с => оба файла видят эту переменную (new_s).
> Потом я вызываю функцию f параметром которой должна быть
> эта структура (т.е. чтобы в функции я мог менять значения
> ее полей ... как я понимаю, параметром должна быть ссылка):
> void f(struct new_s* tmp)
> Но что-то все равно не получается (компилятор отказывается
> принимать такой параметр функции ... ).

Естественно, потому что new_s - это не имя типа.

file.h:

struct s
{
	int a;
	int b;
};

extern struct s new_s;
-----------------------

file1.c:

#include "file.h"
struct s new_s;

-----------------------

file2.c

#include "file.h"

void f(struct s* tmp)
{
//...
}

//....
void g()
{
	f(&new_s);
}

---
Вопрос про структуры в C/C++ 12.06.03 02:06  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> Так, стоп... давай на примерах :) Допустим есть у меня
> такая структура:
> struct s{
> int a;
> int b;
> };
В .h засовываешь только это ^^^
И еще желатеально засунуть туда объявление объекта. То бишь как и говорил dl пишешь extern struct s new_s;

> И я создаю общую переменную, которую я хочу использовать из
> тех 2-х файлов:
> struct s new_s;
Выбираешь один из .c файлов и в одном определяешь структуру (то есть делаешь то что и написано - без extern). Определение должно быть только в ОДНОМ c файле, а объявление включится вместе с .h во все.

> И все это определено в неком .h файле. Я подключаю его и к
> 1.с и к 2.с => оба файла видят эту переменную (new_s).
> Потом я вызываю функцию f параметром которой должна быть
> эта структура (т.е. чтобы в функции я мог менять значения
> ее полей ... как я понимаю, параметром должна быть ссылка):
> void f(struct new_s* tmp)
> {
> ;
> }
Не так. Во первых это не ссылка (ссылки появились в C++), а указатель. Во вторых следует различать ТИП переменной и САМУ переменную. В данном случае переменная new_s имеет тип (struct s), следовательно прототип функции будет следующим
void f(struct s *);

А вызываться будет так:
f(&new_s);

> Но что-то все равно не получается (компилятор отказывается
> принимать такой параметр функции ... ).
> Блин. Что-то я совсем запутался :)
Нужно прочувствовать разницу между типом объекта и самим объектом. Успехов :-)
Вопрос про структуры в C/C++ 12.06.03 02:25  
Автор: dzen Статус: Незарегистрированный пользователь
<"чистая" ссылка>
УРАААААА!!!! ОНА РАБОТАЕТ!!! :)))) ... кхм ... что это я
Спасибо всем! Теперь вот хоть разобрался.
Криво - как ятаган! Но столь же эффективно... 14.06.03 06:19  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
еще в "детстве" методом научного тыка установил, что делать надо именно так и стех пор не перестаю изумляться - почему такая кривизна?

Логически очевидно: все глобальные переменные должны объявляться в хидере проекта, а компилер сам должен был бы разбираться - раз имя хидера совпадает с именем проекта то под все объявленные в нем переменные место выделяется один раз и "на всегда" с доступом из всех .с, в которые он инклюдится.

Почему сделано не так?
Потому что надо знать как работает компилятор (не Urix-like) 14.06.03 10:23  
Автор: Ktirf <Æ Rusakov> Статус: Elderman
Отредактировано 14.06.03 10:24  Количество правок: 1
<"чистая" ссылка>
Компилятор проходит через единицы компиляции совершенно независимо! Инстанцировать переменную, определенную в хедере, в одной единице компиляции (сиречь .c/.cpp-файле) и не сделать этого в другой единице компиляции он в принципе не может, потому что не знает о существовании более чем одной единицы компиляции. Об этом знает линкер, но линкер не может добавлять или удалять такой код, он только связывает отдельные объектные файлы.
Определение и объявление: это две большие разницы.
Предупреждая возможные возражения 14.06.03 17:40  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
Полностью согласен со сказанным, но думаю могут возникнуть некоторые вопросы.
> Компилятор проходит через единицы компиляции совершенно
> независимо! Инстанцировать переменную, определенную в
> хедере, в одной единице компиляции (сиречь .c/.cpp-файле) и
> не сделать этого в другой единице компиляции он в принципе
> не может, потому что не знает о существовании более чем
> одной единицы компиляции. Об этом знает линкер, но линкер

Незнание о других единицах трансляции это "by design" и вводилось как преимущество языка, а не как ограничение. Компиляция со всеми ее синтаксическими и другими анализами, и особенно оптимизацией - сравнительно медленный процесс. Компоновка же (линковка) - несравненно быстрее. Поэтому при фиксаньи баги всего в одном файле не нужно перекомпилировать ВЕСЬ проект (возможно и в не один миллион строк). Достаточно перекомпилировать измененный файл и пересобрать его со старыми откомпилированными объектниками.

Раздельная компиляция это основа модульного программирования. При котором в пределах модуля можно производить ЛЮБЫЕ изменения, если не затрагивается его внешний интерфес. Внешний интерфес модуля как раз и выносится в .h файл, а реализация остается в .c

> не может добавлять или удалять такой код, он только
> связывает отдельные объектные файлы.
> Определение и объявление: это две большие разницы.
Использовать модуль при помощи его интерфейса (подключая .h) может кто угодно, а реализация в любом случае должна быть одна. То есть объявлять о желании использовать переменную могут любые модули. А выделять реальную память (определять переменную) под нее должна только реализация.
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach