Столкнулся с такой манифестацией глобальнопеременнофобии:
Для выполенния одного задания на С я написал некий простенький garbage collector. Есть функции safe_malloc/safe_realloc/safe_free, пользуясь которыми мне не обязательно освобождать память, они все помнят и сами освобождают неосвобожденное. Указатель на массив указателей на выданные блоки памяти я храню в глобальной переменной как и счетчик оных.
Получил назад свое задание, сняли 3 балла за использование глобальных переменных. Считаю, что это несправедливо, потому что не вижу никакого рационального способа убрать их и не устраивать каких-то сложных и непонятных трюков. Есть случаи, когда глобальные переменные оправданы, то зачем за это снимать? :-\
Что вы думаете? Какое решение без глобалов вы можете предложить?
Вместо глобальных переменных лучше использовать статические.
Цитата: Python от марта 1, 2011, 15:11
Вместо глобальных переменных лучше использовать статические.
Логично. Но если нужно общую между двумя-тремя функциями, то как?
Переменная объявляется как static, но не внутри функции, а за ее пределами. Она будет доступной для всех функций в этом модуле и недоступной для других модулей.
Цитата: RawonaM от марта 1, 2011, 15:07
Что вы думаете? Какое решение без глобалов вы можете предложить?
Ты ничего не забыл показать? :eat:
Цитата: Python от марта 1, 2011, 15:25
Переменная объявляется как static, но не внутри функции, а за ее пределами. Она будет доступной для всех функций в этом модуле и недоступной для других модулей.
Ну так это же и есть глобальная, только для этого модуля и у нее те же недостатки как и у "нестатических" глобальных. Не уверен, что к глобальным "статическим" отнеслись бы по-другому.
В общем-то да, вы правы, что так было бы лучше их определить, но функционально ничего это не меняет.
Цитата: myst от марта 1, 2011, 15:32
ЦитироватьЧто вы думаете? Какое решение без глобалов вы можете предложить?
Ты ничего не забыл показать? :eat:
Например?
А зачем? Я вроде всю ситуацию ясно объяснил.
Цитата: RawonaM от марта 1, 2011, 15:35
Ну так это же и есть глобальная, только для этого модуля и у нее те же недостатки как и у "нестатических" глобальных. Не уверен, что к глобальным "статическим" отнеслись бы по-другому.
Если суть претензии была в необоснованно широкой области видимости, а локальная переменная не годится, то всё правильно Python советует. Других вариантов в Си нет.
Цитата: RawonaM от марта 1, 2011, 15:35
но функционально ничего это не меняет.
Меняет, если имя переменной каким-то образом совпало с другим идентификатором в библиотеках или в другом модуле. Кроме того, глобальная переменная считается дыркой в безопасности: при желании, можно написать другой модуль, изменяющий эту глобальную переменную или читающий ее данные, и, например, внедрить его в библиотеку, с которой этот модуль линкуется.
Цитата: RawonaM от марта 1, 2011, 15:35
Не уверен, что к глобальным "статическим" отнеслись бы по-другому.
А я уверен. Объективно есть ситуации, когда переменная должна использоваться несколькими функциями, но делать ее глобальной и доступной для всех модулей — плохой стиль. Глобальной следует делать переменную, если она рассчитана на непосредственный доступ и изменение из других модулей, иначе она должна быть (общей) статической.
Цитата: RawonaM от марта 1, 2011, 16:07
А зачем? Я вроде всю ситуацию ясно объяснил.
Хотя бы затем, чтобы решить, насколько они правы, и посоветовать что-то конкретное. На сферических конях ведь далеко не уедешь. :donno:
Цитата: myst от марта 1, 2011, 16:08
Если суть претензии была в необоснованно широкой области видимости, а локальная переменная не годится, то всё правильно Python советует. Других вариантов в Си нет.
Так я с Pythonoм согласен. Но мне кажется что претензии на этом не ограничиваются, мне кажется действует тотальный запрет на глобальные (т.е. вне функций).
Цитата: Python от марта 1, 2011, 16:10
Кроме того, глобальная переменная считается дыркой в безопасности: при желании, можно написать другой модуль, изменяющий эту глобальную переменную или читающий ее данные, и, например, внедрить его в библиотеку, с которой этот модуль линкуется.
:D Жесть. Всё-таки экстравагантных фантазий нашему Python'у не занимать.
Цитата: RawonaM от марта 1, 2011, 16:13
Так я с Pythonoм согласен. Но мне кажется что претензии на этом не ограничиваются, мне кажется действует тотальный запрет на глобальные (т.е. вне функций).
Если бы это были плюсы, я бы ещё понял. В си и так слишком мало средств, чтобы ещё какие-то тотальные запреты вводить. Другое дело, что возможно существует решение без глобальных переменных, которое ты не нашел.
Цитата: Python от марта 1, 2011, 16:10
Цитироватьно функционально ничего это не меняет.
Меняет, если имя переменной каким-то образом совпало с другим идентификатором в библиотеках или в другом модуле.
А что, если я в другом модуле определю такой же индентификатор, то они будут конфликтовать? По-моему пока нет декларации extern в других модулях, они не видят эту переменную.
Цитата: myst от марта 1, 2011, 16:14
ЦитироватьКроме того, глобальная переменная считается дыркой в безопасности: при желании, можно написать другой модуль, изменяющий эту глобальную переменную или читающий ее данные, и, например, внедрить его в библиотеку, с которой этот модуль линкуется.
:D Жесть. Всё-таки экстравагантных фантазий нашему Python'у не занимать.
Но он же правильно говорит.
Значит выходит, что я неправильно понял, что не понравилось проверяющему?..
Блин, у меня нет с ним прямой связи, это напрягает. И вообще семестр уже закончился и теперь хрен кого найдешь.
Цитата: myst от марта 1, 2011, 16:17
ЦитироватьТак я с Pythonoм согласен. Но мне кажется что претензии на этом не ограничиваются, мне кажется действует тотальный запрет на глобальные (т.е. вне функций).
Если бы это были плюсы, я бы ещё понял. В си и так слишком мало средств, чтобы ещё какие-то тотальные запреты вводить. Другое дело, что возможно существует решение без глобальных переменных, которое ты не нашел.
Не знаю, чем тебе поможет код...
Ну вот:
/* dynamic array of pointers to allocated buffers */
void **alloc_ptrs = NULL;
/* counter of allocated buffers */
int alloc_cnt = 0;
/*
* Allocates memory, storing a pointer for later automatic freeing in case of
* exiting on error.
*/
void *safe_malloc(size_t size)
{
void *new_buffer, *tmp;
/* resize pointer array and allocate the buffer */
tmp = realloc(alloc_ptrs, sizeof(void*)*(alloc_cnt+1));
if (tmp == NULL || NULL == (new_buffer = malloc(size)))
safe_exit(ALLOC_ERROR);
/* update pointers array and counter*/
alloc_ptrs = tmp;
alloc_cnt++;
alloc_ptrs[alloc_cnt-1] = new_buffer;
return new_buffer;
}
/*
* Resizes the buffer that ptr was previously allocated with safe_malloc.
* If ptr is NULL, the function is identical to safe_malloc.
*/
void *safe_realloc(void *ptr, size_t size)
{
int i;
/* allocating new buffer */
if (ptr == NULL)
return safe_malloc(size);
/* freeing a buffer */
if (size == 0)
{
safe_free(ptr);
return NULL;
}
/* reallocate and update the pointer in array */
for (i = 0; i < alloc_cnt; i++)
if (alloc_ptrs[i] == ptr)
{
if ((ptr = realloc(ptr, size)) == NULL)
safe_exit(ALLOC_ERROR);
alloc_ptrs[i] = ptr;
return alloc_ptrs[i];
}
/* if we get here, this pointer was not previously allocated */
return NULL;
}
Цитата: RawonaM от марта 1, 2011, 16:18
Но он же правильно говорит.
Сейчас я тебе открою тайну, но только никому, хорошо? :tss:
Если у тебя есть доступ к исходникам или объектникам, ты можешь любую переменную сделать глобальной при желании. Смекаешь? :)
Цитата: myst от марта 1, 2011, 16:27
ЦитироватьНо он же правильно говорит.
Сейчас я тебе открою тайну, но только никому, хорошо? :tss:
Если у тебя есть доступ к исходникам или объектникам, ты можешь любую переменную сделать глобальной при желании. Смекаешь? :)
Если у тебя есть только обж и гедер — что ты можешь сделать? Даже если ты формат обжа знаешь, то у другого компилятора он может быть другим.
Мы же говорим о теории программирования, а не о том, как похакать можно.
Цитата: RawonaM от марта 1, 2011, 16:22
Ну вот:
А где автоматическое освобождение? :what:
Ну что, весь код прямо что ли закопипастить? Я релевантные куски :)
Принцип ясен. Там где автоосвобождение, оно тоже эту же глобалку читает.
Цитата: RawonaM от марта 1, 2011, 16:32
Если у тебя есть только обж и гедер — что ты можешь сделать? Даже если ты формат обжа знаешь, то у другого компилятора он может быть другим.
Мы же говорим о теории программирования, а не о том, как похакать можно.
При чём тут теория, если речь о конкретных вещах?
На уровне сишных объектников нет никакой защиты, она там просто не нужна. Поэтому фантазии о дырках в защите на этом уровне очень юмористичны.
Цитата: RawonaM от марта 1, 2011, 16:36
Ну что, весь код прямо что ли закопипастить? Я релевантные куски :)
Принцип ясен. Там где автоосвобождение, оно тоже эту же глобалку читает.
Не, ну ты можешь на пальцах объяснить логику. :)
Цитата: myst от марта 1, 2011, 16:37
Не, ну ты можешь на пальцах объяснить логику. :)
А что там непонятного еще?? При выходе вызывается safe_exit() (устанавливается atexit-ом, например), он все и освобождает.
Интерфейс определён заданием, или ты его сделал по аналогии со стандартными функциями?
В коде не хватает инклудов. Если используется realloc, то должен быть как минимум #include <stdlib.h> (либо инклуд, ссылающийся на него, например, stdio.h).
Цитата: myst от марта 1, 2011, 16:36
При чём тут теория, если речь о конкретных вещах?
На уровне сишных объектников нет никакой защиты, она там просто не нужна. Поэтому фантазии о дырках в защите на этом уровне очень юмористичны.
-1. Теория — это теория. Можно создать сишные объектники с защитой, никто не запрещает.
Цитата: Python от марта 1, 2011, 16:44
В коде не хватает инклудов. Если используется realloc, то должен быть как минимум #include <stdlib.h> (либо инклуд, ссылающийся на него, например, stdio.h).
Это отрывок кода.
Цитата: myst от марта 1, 2011, 16:27
Если у тебя есть доступ к исходникам или объектникам, ты можешь любую переменную сделать глобальной при желании. Смекаешь? :)
С исходниками понятно, а как это проделать с объектниками? Нас такому не учили :(
Код рабочий, уже давно все написано, скомпайлено, отлажено и сдано, поэтому искать там ошибки компиляции не надо.
Цитата: RawonaM от марта 1, 2011, 16:44
-1. Теория — это теория. Можно создать сишные объектники с защитой, никто не запрещает.
В каком месте это защита? :o
Цитата: myst от марта 1, 2011, 16:43
Интерфейс определён заданием, или ты его сделал по аналогии со стандартными функциями?
В задании вообще ничего об этом нет. Задание было — написать С-препроцессор.
Просто я задолбался писать f = malloc... if (f==null) {кучу действий...} и так 40 раз на 5 квадратных строк.
Решил раз и навсегда покончить с этим, написать такого рода мусорщика. С тех пор присоединяю его к каждой программе и не мучаюсь :)
Короче, эти переменные спрятать, конечно, можно, но я бы их просто статиками объявил, ибо keep it simple, stupid. Если я всё правильно понял.
Цитата: RawonaM от марта 1, 2011, 16:48
Цитата: myst от марта 1, 2011, 16:43
Интерфейс определён заданием, или ты его сделал по аналогии со стандартными функциями?
В задании вообще ничего об этом нет. Задание было — написать С-препроцессор.
Просто я задолбался писать f = malloc... if (f==null) {кучу действий...} и так 40 раз на 5 квадратных строк.
Решил раз и навсегда покончить с этим, написать такого рода мусорщика. С тех пор присоединяю его к каждой программе и не мучаюсь :)
Может, им вообще твоя самодеятельность не понравилась. Может, освобождать память только перед самым выходом не есть гуд, я не знаю.
Цитата: myst от марта 1, 2011, 16:49
Короче, эти переменные спрятать, конечно, можно, но я бы их просто статиками объявил, ибо keep it simple, stupid. Если я всё правильно понял.
Статики в смысле глобал-статик? Я вообще не понимаю, зачем к ним слово статик примешали, не надо путать.
Цитата: myst от марта 1, 2011, 16:52
Может, им вообще твоя самодеятельность не понравилась. Может, освобождать память только перед самым выходом не есть гуд, я не знаю.
Нет, с этим не было проблем. Да и я освобождаю ее как обычно, только на выходе при ошибках все сразу освобождается и баги таким образом можно выцедить (вставлется в safe_exit проверка и выдается предупреждение, что не вся память освобождена).
Просто каждый раз когда открываешь файл или запрашиваешь память, есть шанс, что тебе откажут, каким образом можно освободить всю память и выйти из программы с сообщением об ошибке? Что бы с этим не заморачиваться, я так сделал.
Цитата: myst от марта 1, 2011, 16:49
Короче, эти переменные спрятать, конечно, можно
Например как?
Всё-таки тема теории защиты не раскрыта :(
Я такого не слышал (впрочем и си я никогда не изучал)
Цитата: RawonaM от марта 1, 2011, 16:53
Статики в смысле глобал-статик? Я вообще не понимаю, зачем к ним слово статик примешали, не надо путать.
Не распарсил последнее предложение. Короче, модификатор static надо было к глобальным переменным приписать. К вспомогательным функциями, которые используются только в данном модуле, тоже надо его приписывать, чтобы их область видимости не была шире необходимого.
К стати, при желании safe_realloc и safe_malloc можно объединить в одну функцию и вместо safe_malloс(size) вызывать safe_realloc(NULL, size). Впрочем, особого смысла в этом нет.
Цитата: Чайник777 от марта 1, 2011, 16:59
Всё-таки тема теории защиты не раскрыта :(
Я такого не слышал (впрочем и си я никогда не изучал)
Как не раскрыта? Я же сказал, защиты на уровне объектников нет и никогда не было. Там некого и не от кого защищать. Это детали для сборки программы. Программисту нет необходимости в свою программу чего-то там нелегально внедрять, если у него не раздвоение личности, конечно.
Цитата: Чайник777 от марта 1, 2011, 16:59
Всё-таки тема теории защиты не раскрыта :(
Я такого не слышал (впрочем и си я никогда не изучал)
Это дело не только в Си, возьмите любой современный язык и подумайте, зачем нужны private мемберы. То же самое и static для глобалов в С.
Цитата: myst от марта 1, 2011, 17:00
Короче, модификатор static надо было к глобальным переменным приписать.
С этим я согласен, но замечание проверяющего я понял совсем не так. Имхо, не этого они хотели.
Цитата: myst от марта 1, 2011, 17:00
ЦитироватьЯ вообще не понимаю, зачем к ним слово статик примешали, не надо путать.
Не распарсил последнее предложение.
static — это переменная, которая не automatic, т.е. не меняется каждый раз при входе в функцию. По сути это глобальная переменная, которая видна только в этой функции.
Все определенные вне функций переменные - статические по определению. Слово static для глобалов в качестве ~private — дурацкая метонимия.
Цитата: myst от марта 1, 2011, 17:04
Как не раскрыта? Я же сказал, защиты на уровне объектников нет и никогда не было. Там некого и не от кого защищать.
Ты же сам предложил объектник поменять! От тебя и защищать.
Если ты обещаешь в объектники не лазить, то static от твоих изменений защитит.
Цитата: RawonaM от марта 1, 2011, 17:06
возьмите любой современный язык и подумайте, зачем нужны private мемберы. То же самое и static для глобалов в С.
Я думаю, врядли для того, о чём писал Python.
Цитата: Python от марта 1, 2011, 17:02
К стати, при желании safe_realloc и safe_malloc можно объединить в одну функцию и вместо safe_malloс(size) вызывать safe_realloc(NULL, size). Впрочем, особого смысла в этом нет.
Так они же по аналогии с malloc и realloc. 100% совместимые. Можно сделать для любой программы #define malloc safe_malloc и задебагировать, мой код выдаст все ошибки неосвобождения памяти.
Цитата: RawonaM от марта 1, 2011, 17:06
static — это переменная, которая не automatic, т.е. не меняется каждый раз при входе в функцию. По сути это глобальная переменная, которая видна только в этой функции.
Все определенные вне функций переменные - статические по определению. Слово static для глобалов в качестве ~private — дурацкая метонимия.
А, вот ты про что. Это они ключевые слова сэкономили. :)
Цитата: Чайник777 от марта 1, 2011, 17:09
Цитироватьвозьмите любой современный язык и подумайте, зачем нужны private мемберы. То же самое и static для глобалов в С.
Я думаю, врядли для того, о чём писал Python.
Именно для того.
Цитата: myst от марта 1, 2011, 17:10
А, вот ты про что. Это они ключевые слова сэкономили. :)
Вот-вот. Экономисты блин :)
Цитата: RawonaM от марта 1, 2011, 17:08
Ты же сам предложил объектник поменять! От тебя и защищать.
Я не предложил, но показал, что это никакая не защита от злодеев. Злодеев придумал Python, а не я, если что. :eat:
Цитата: myst от марта 1, 2011, 17:13
ЦитироватьТы же сам предложил объектник поменять! От тебя и защищать.
Я не предложил, но показал, что это никакая не защита от злодеев. Злодеев придумал Python, а не я, если что. :eat:
Так а я говорю, что защита.
Цитата: myst от марта 1, 2011, 17:04
Программисту нет необходимости в свою программу чего-то там нелегально внедрять, если у него не раздвоение личности, конечно.
Ну а если, допустим, каждый программист пишет лишь небольшкю часть кода, которая компилируется отдельно от остальных (и, например, разработчик GUI формально не имеет доступа к работе базы данных с конфиденциальной информацией)? Другое дело, такой метод защиты программы уже давно не рассматривается как защита.
Цитата: Чайник777 от марта 1, 2011, 17:14
ЦитироватьИменно для того.
:o
Дык, инкапсуляция же.
Инкапсуляцию (http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)) можно рассматривать как защиту от злодеев лишь в шутку:
Цитировать
Hiding the internals of the object protects its integrity by preventing users from setting the internal data of the component into an invalid or inconsistent state. A benefit of encapsulation is that it can reduce system complexity, and thus increases robustness, by allowing the developer to limit the interdependencies between software components.
Цитата: Python от марта 1, 2011, 17:15
ЦитироватьПрограммисту нет необходимости в свою программу чего-то там нелегально внедрять, если у него не раздвоение личности, конечно.
Ну а если, допустим, каждый программист пишет лишь небольшкю часть кода, которая компилируется отдельно от остальных (и, например, разработчик GUI формально не имеет доступа к работе базы данных с конфиденциальной информацией)? Другое дело, такой метод защиты программы уже давно не рассматривается как защита.
Все правильно Питон говорит. Программистов может быть не один и не два. Даже если человек один.
Например один человек в прошлом году написал, в этом году он уже не тот же программист, ибо он уже все забыл.
Принцип инкапсуляции какбе. Все современные языки на этом основаны и это один из столпов ООП.
Цитата: Чайник777 от марта 1, 2011, 17:19
Инкапсуляцию можно рассматривать как защиту от злодеев лишь в шутку:
"Злодеев" мы тут как раз в шутку и употребляем.
Цитата: Python от марта 1, 2011, 17:15
Ну а если, допустим, каждый программист пишет лишь небольшкю часть кода, которая компилируется отдельно от остальных (и, например, разработчик GUI формально не имеет доступа к работе базы данных с конфиденциальной информацией)?
Не улавливаю связи разработчика куска программы с доступом, точнее с запретом доступа, к какой-то там базе данных.
Цитата: RawonaM от марта 1, 2011, 17:16
Дык, инкапсуляция же.
Это защита от дурака, а не от злодея. ;D
Цитата: RawonaM от марта 1, 2011, 17:20
"Злодеев" мы тут как раз в шутку и употребляем.
Э не, Python говорил об эксплоите глобальной переменной.
Цитата: myst от марта 1, 2011, 17:26
Цитировать"Злодеев" мы тут как раз в шутку и употребляем.
Э не, Python говорил об эксплоите глобальной переменной.
Ну тут нужен злодей который не может обж изменить. Какбе тут есть элемент криминальной защиты, но на уровне цепочки на дверях.
Цитата: myst от марта 1, 2011, 17:24
ЦитироватьДык, инкапсуляция же.
Это защита от дурака
Ты пишешь код без указания области видимости? :) Зачем тебе защита? :)
Цитата: RawonaM от марта 1, 2011, 17:29
Ну тут нужен злодей который не может обж изменить. Какбе тут есть элемент криминальной защиты, но на уровне цепочки на дверях.
Какбэ тут нет вообще криминальной защиты. То, о чём мы говорим, создано для управления связями во время линковки, чтобы не надо было следить за уникальностью переменных во всех модулях.
Цитата: RawonaM от марта 1, 2011, 17:30
Ты пишешь код без указания области видимости? :) Зачем тебе защита? :)
Чтобы уберечься от дурака же. :donno:
Цитата: myst от марта 1, 2011, 17:34
Чтобы уберечься от дурака же. :donno:
Это какое-то странное понимание инкапсуляции :)
Цитата: myst от марта 1, 2011, 17:33
Какбэ тут нет вообще криминальной защиты. То, о чём мы говорим, создано для управления связями во время линковки, чтобы не надо было следить за уникальностью переменных во всех модулях.
А точно линкер будет ругаться на одинаковые имена в разных модулях? Это в стандарте определено?
Цитата: myst от марта 1, 2011, 17:33
Какбэ тут нет вообще криминальной защиты. То, о чём мы говорим, создано для управления связями во время линковки, чтобы не надо было следить за уникальностью переменных во всех модулях.
Тем не менее, к глобальным переменным и публичным полям отношение более строгое, чем к функциям/методам.
Цитата: Python от марта 1, 2011, 17:42
Тем не менее, к глобальным переменным и публичным полям отношение более строгое, чем к функциям/методам.
Ичо?
Цитата: RawonaM от марта 1, 2011, 17:41
А точно линкер будет ругаться на одинаковые имена в разных модулях?
Не не будет, будет по фазе Луны линковать.
Цитата: myst от марта 1, 2011, 17:55
ЦитироватьА точно линкер будет ругаться на одинаковые имена в разных модулях?
Не не будет, будет по фазе Луны линковать.
Не понял...
Как он, по-твоему, выберет правильную связь в этой ситуации?
Цитата: myst от марта 1, 2011, 17:58
Как он, по-твоему, выберет правильную связь в этой ситуации?
А ее нет, какая там связь? Это разные переменные, просто имя совпало.
Чтобы была одна, нужна extern декларация во всех, кроме одного, где определение.
ЦитироватьИчо?
Принято считать, что через несанкционированный/ошибочный доступ к переменным можно нанести больше вреда, чем через вызов функций, которые, в идеале, должны содержать в себе определенную защиту от дурака. Хотя, безусловно, во многих случаях программистские догмы соблюдаются лишь по той причине, что так завещали древние.
Цитата: RawonaM от марта 1, 2011, 18:00
Цитата: myst от марта 1, 2011, 17:58
Как он, по-твоему, выберет правильную связь в этой ситуации?
А ее нет, какая там связь? Это разные переменные, просто имя совпало.
Чтобы была одна, нужна extern декларация во всех, кроме одного, где определение.
Но если в одна и та же переменная или функция объявлена как глобальная в двух модулях и как extern — в третьем, то третий модуль может связаться с любым из первых двух.
Цитата: Python от марта 1, 2011, 18:12
Цитата: RawonaM от марта 1, 2011, 18:00
Цитата: myst от марта 1, 2011, 17:58
Как он, по-твоему, выберет правильную связь в этой ситуации?
А ее нет, какая там связь? Это разные переменные, просто имя совпало.
Чтобы была одна, нужна extern декларация во всех, кроме одного, где определение.
Но если в одна и та же переменная или функция объявлена как глобальная в двух модулях и как extern — в третьем, то третий модуль может связаться с любым из первых двух.
А-а, ну если так то да. Действительно.
Цитата: RawonaM от марта 1, 2011, 18:00
Цитата: myst от марта 1, 2011, 17:58
Как он, по-твоему, выберет правильную связь в этой ситуации?
А ее нет, какая там связь? Это разные переменные, просто имя совпало.
Чтобы была одна, нужна extern декларация во всех, кроме одного, где определение.
Ты вообще представляешь, как линкёр работает?
Цитата: Python от марта 1, 2011, 18:01
Принято считать, что через несанкционированный/ошибочный доступ к переменным можно нанести больше вреда, чем через вызов функций, которые, в идеале, должны содержать в себе определенную защиту от дурака.
КО одобряет, но я так и не понял, зачем мне об этом рассказывать. :donno:
Цитата: myst от марта 1, 2011, 18:20
Цитата: RawonaM от марта 1, 2011, 18:00
Цитата: myst от марта 1, 2011, 17:58
Как он, по-твоему, выберет правильную связь в этой ситуации?
А ее нет, какая там связь? Это разные переменные, просто имя совпало.
Чтобы была одна, нужна extern декларация во всех, кроме одного, где определение.
Ты вообще представляешь, как линкёр работает?
А почему бы мне не представлять? Я тут компилятор написал, еще б чуть-чуть и линкер уже б был :)
Мой линкер разрешает одинаковые имена в разных модулях. Чтобы переменная была доступна в другом модуле, у меня она должна быть объявлена как типа публик, а в другом модуле как екстерн, а совпадение идентификаторов в других случаях никому не мешает.
А чё тогда странные вопросы задаёшь?
Без странных вопросов не бывает ни науки ни обучения :)
Скоро начнется πυθωνομυστομαχία, или мне можно заниматься своими делами?
Какая махия? Всё уже кончилось.
Как обойтись без глобальных переменных? Очень просто. Указатель на область памяти сделать первым параметром всех функций - так при каждом вызове функции явно будет видно, где, собственно, она всё это размещает.
Цитата: amdf от марта 5, 2011, 10:29
Как обойтись без глобальных переменных? Очень просто. Указатель на область памяти сделать первым параметром всех функций - так при каждом вызове функции явно будет видно, где, собственно, она всё это размещает.
По-моему вы чего-то недопоняли. Это сделать невозможно, а если сильно извратиться, то будет совершенно непонятное спагетти.
Если передавать как первый параметр, а эти функции надо вызывать из других модулей, значит эта переменная будет храниться где-то извне, тогда в модулях извне мы тоже не хотим использовать глобальные переменные, значит в каждую из всех функций во всех модулях, использующих аллокацию памяти, нужно добавлять этот параметр.
В принципе, можно аллокатор с деаллокатором объединить в одну подпрограмму, и указатель на массив указателей спрятать внутри неё. Но это плохой стиль.
Цитата: myst от марта 5, 2011, 10:59
В принципе, можно аллокатор с деаллокатором объединить в одну подпрограмму, и указатель на массив указателей спрятать внутри неё. Но это плохой стиль.
Де це ты подцепил ихсочное слово "подпрограмма"? Корежит.
Конечно, так можно сделать, но это всего лишь пляски которые ничего не меняют, кроме еще большего снижения понимания. Глобальнопеременнофобия ведь связана с тем, что неясно сразу кто как и зачем использует эти переменные. Что в специальной для этого функции, что глобальные, один хрен.
Цитата: RawonaM от марта 5, 2011, 11:22
Де це ты подцепил ихсочное слово "подпрограмма"? Корежит.
Привыкай к правильной терминологии. :)
Цитата: RawonaM от марта 5, 2011, 11:22
Конечно, так можно сделать, но это всего лишь пляски которые ничего не меняют, кроме еще большего снижения понимания. Глобальнопеременнофобия ведь связана с тем, что неясно сразу кто как и зачем использует эти переменные. Что в специальной для этого функции, что глобальные, один хрен.
:??? Ты как будто со мной споришь?
А ещё все глобальные переменные и функции можно упрятать внутрь класса.
Цитата: amdf от марта 7, 2011, 20:00
А ещё все глобальные переменные и функции можно упрятать внутрь класса.
Тогда сейчас же отправляйтесь искать классы в C. О результатах непременно расскажите нам.
Да, очень бесит когда С++ называют С. Может amdf с такими переобщался :)