Модульная загадка про константу
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 01.07.05 09:32
Оценка: 4 (1) -1 :))) :))) :))) :))
  • Модульная загадка про константу

    Рассмотрим модульную расширяемую систему. Создадим первый модуль, в котором определим константу, и скомпилируем его. Создадим второй модуль, который импортирует первый модуль и использует определённую ранее константу. Скомпилируем второй модуль. А теперь возьмем первый модуль, изменим в нем значение константы на другое и скомпилируем его. Второй модуль перекомпилировать не будем. Запустим на выполнение старый второй модуль вместе с новым первым. Что произойдет? Что реально происходит в таких модульных расширяемых системах как Oberon и .NET я сообщу позже, а сейчас давайте подумаем что должно происходить. Идеальным было бы так, чтобы второй модуль использовал новое значение константы из первого модуля. Не так ли? Что этому мешает? Я думаю, что как минимум на это есть две причины. Во-первых, при компиляции второго модуля константа могла быть нужна компилятору, например, для определения размера переменных в том случае если бы она была использована, например, как размер (не динамического) массива. Во-вторых, используя константу вместо переменной компилятор может осуществить оптимизацию. Первая причина в отличие от второй является фатальной. Выходит, мы не можем ожидать от второго модуля использование константы из первого модуля? Но, не кажется ли Вам, что это какой-то бред? Второй модуль использует константу из первого модуля, которую использовать не может — точно бред, не так ли? Выходит в модульных расширяемых системах просто напросто должно быть запрещено экспортирование / имортирование констант! Ибо это просто невозможно физически реализовать.




  • Что реально происходит в Oberon (BlackBox 1.5 BETA):
    MODULE Module1;
    
      CONST N* = 10; (* Потом меняем ее на 20 *)
            
    END Module1.

    MODULE Module2;
    
      IMPORT StdLog, Module1;
        
      PROCEDURE Do*;
      BEGIN
        IF Module1.N = 10 THEN
          StdLog.String("Module1.N = 10"); StdLog.Ln
        ELSE
          StdLog.String("Module1.N # 10"); StdLog.Ln
        END
      END Do;
            
    END Module2.

    При попытке запустить на выполнение старого второго модуля с новым первым происходит ошибка:

    "command error: object Module1.N inconsistently imported from Module2"





  • Что реально происходит в .NET (1.1)
    namespace Test
    {
        public sealed class Module1
        {
            public const int N = 10; /* Потом меняем ее на 20 */
        }
    }

    namespace Test
    {
        class Program
        {
            static void Main(string[] args)
            {
                if(Module1.N == 10)
                {
                    System.Console.WriteLine("Module1.N = 10");
                }
                else
                {
                    System.Console.WriteLine("Module1.N # 10");
                }
                System.Console.ReadLine();
            }
        }
    }

    Запускаем на выполнение старый второй модуль с новым первым, в консоли преспокойно печатается какая-то ерунда:

    "Module1.N = 10"

    ведь в новом первом модуле Module1.N = 20. Совсем не ожиданно, однако...
  • Re: Модульная загадка про константу
    От: gbear Россия  
    Дата: 01.07.05 09:41
    Оценка: +1 -1
    Здравствуйте, Сергей Губанов, Вы писали:

    Константа, она на то и константа. Если бы вычисление её значения переводилось бы в run-time, то это была бы уже не константа. Так... свойство.

    ---
    С уважением, Сиваков Константин.

    P.S. Это по поводу .NET поведения.
    Re: Модульная загадка про константу
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 01.07.05 09:49
    Оценка: 5 (3) +2
    Здравствуйте, Сергей Губанов, Вы писали:

    СГ>Запускаем на выполнение старый второй модуль с новым первым, в консоли преспокойно печатается какая-то ерунда:

    СГ>

    СГ>"Module1.N = 10"

    СГ>ведь в новом первом модуле Module1.N = 20. Совсем не ожиданно, однако...

    Извини, не прочел все эссе целиком (в лом).

    Но, думаю я и так угадаю. Спецификации нужно читать. С целью увеличения быстродействия дотнет копирует (propagate) константы в применяемые модули. Другими словами константа — это ее значение.

    Если тебе нужна неизменяемая переменная которая не будет подставляться по месту, то пользуйся модификатором readonly:
    class Test
    {
        public readonly int Test;
    }
    ... << RSDN@Home 1.1.4 beta 7 rev. 466>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[2]: Модульная загадка про константу
    От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
    Дата: 01.07.05 09:51
    Оценка:
    Здравствуйте, gbear, Вы писали:

    G>Константа, она на то и константа. Если бы вычисление её значения переводилось бы в run-time, то это была бы уже не константа. Так... свойство.


    Я про то и говорю — значит в модульных расширяемых системах должен быть запрещен импорт / экспорт констант!
    Re: Модульная загадка про константу
    От: Cyberax Марс  
    Дата: 01.07.05 09:51
    Оценка: 16 (2) +1
    Сергей Губанов wrote:

    > # Выходит в модульных расширяемых системах просто напросто должно быть

    > запрещено экспортирование / имортирование констант! Ибо это просто
    > невозможно физически реализовать.

    В нормальных языках (то есть в C/C++) такой проблемы нет — при
    модификации константы в h-файле просто все зависимое от нее
    перекомпилируется.

    В C# тоже нет проблемы — при изменении сборки меняется ее контрольная
    сумма, и все зависимое от нее будет перекомпилировано. При попытке
    совместить несовместимые сборки — получится exception.

    --
    С уважением,
    Alex Besogonov (alexy@izh.com)
    Posted via RSDN NNTP Server 1.9
    Sapienti sat!
    Re[2]: Модульная загадка про константу
    От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
    Дата: 01.07.05 09:56
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD> Спецификации нужно читать.


    Большое спасибо, но я ни сколько не сомневался, что данное поведение обязательно описано в спецификации.

    Однако поставленный вопрос, собственно, заключается в смысле экспорта / импорта констант в модульных расширяемых системах, ведь это не возможно реализовать физически.
    Re[2]: Модульная загадка про константу
    От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
    Дата: 01.07.05 10:00
    Оценка: -2
    Здравствуйте, Cyberax, Вы писали:

    C>В нормальных языках (то есть в C/C++) такой проблемы нет — при

    C>модификации константы в h-файле просто все зависимое от нее
    C>перекомпилируется.

    Эти языки не модульные. Нет модулей — нет проблем.

    C>В C# тоже нет проблемы — при изменении сборки меняется ее контрольная

    C>сумма, и все зависимое от нее будет перекомпилировано. При попытке
    C>совместить несовместимые сборки — получится exception.

    Я только что привел пример где этого exception нет, зато преспокойно распечатывается "Module1.N = 10", в то время когда Module1.N = 20.
    Re[3]: Модульная загадка про константу
    От: Mr. None Россия http://mrnone.blogspot.com
    Дата: 01.07.05 10:04
    Оценка: +3
    Здравствуйте, Сергей Губанов, Вы писали:

    СГ>Здравствуйте, Cyberax, Вы писали:


    C>>В нормальных языках (то есть в C/C++) такой проблемы нет — при

    C>>модификации константы в h-файле просто все зависимое от нее
    C>>перекомпилируется.

    СГ>Эти языки не модульные. Нет модулей — нет проблем.


    C>>В C# тоже нет проблемы — при изменении сборки меняется ее контрольная

    C>>сумма, и все зависимое от нее будет перекомпилировано. При попытке
    C>>совместить несовместимые сборки — получится exception.

    СГ>Я только что привел пример где этого exception нет, зато преспокойно распечатывается "Module1.N = 10", в то время когда Module1.N = 20.


    Вы не использовали strong-name для своей сборки, то есть не рассчитывали её контрольную сумму и не подписывали её — а, следовательно, это ваша сугубо личная проблема. Потому что такие сборки годятся только для написания тестов и отладочных версий приложений. Выпускаемая в свет сборка должна иметь строгое имя...
    Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
    Re: Модульная загадка про константу
    От: stalcer Россия  
    Дата: 01.07.05 11:16
    Оценка:
    Здравствуйте, Сергей Губанов, Вы писали:

    На самом деле эту проблему можно решить. Особенно для таких систем, как .Net. Там есть VM, которая делает всякие служебные действия во время выполнения программы. Например, размеры структур, объектов и т.п. считаются во время выполнения джит компилятором. Тогда-же считаются и размеры стековых фреймов. Так что никакой проблемы-то и нет. Джит с таким же успехом может посчитать все константы и вписать значения куда нужно в коде и т.п.

    Почему-то это пока не реализовано.
    http://www.lmdinnovative.com (LMD Design Pack)
    Re[3]: Модульная загадка про константу
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 01.07.05 11:23
    Оценка: +2
    Здравствуйте, Сергей Губанов, Вы писали:

    СГ>Однако поставленный вопрос, собственно, заключается в смысле экспорта / импорта констант в модульных расширяемых системах, ведь это не возможно реализовать физически.


    Для многих задач быстродействие важно, а межмодульная жизнь констрант нет. В общем, есть выбор. Хочешь используешь константны хочешь перменные с readonly.
    ... << RSDN@Home 1.1.4 beta 7 rev. 466>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[3]: Модульная загадка про константу
    От: Cyberax Марс  
    Дата: 01.07.05 12:09
    Оценка:
    Сергей Губанов wrote:

    > C>В нормальных языках (то есть в C/C++) такой проблемы нет — при

    > C>модификации константы в h-файле просто все зависимое от нее
    > C>перекомпилируется.
    > Эти языки не модульные. Нет модулей — нет проблем.

    Модульные, просто модули делаются по-другому.

    > C>В C# тоже нет проблемы — при изменении сборки меняется ее контрольная

    > C>сумма, и все зависимое от нее будет перекомпилировано. При попытке
    > C>совместить несовместимые сборки — получится exception.
    > Я только что привел пример где этого exception нет, зато преспокойно
    > распечатывается "Module1.N = 10", в то время когда Module1.N = 20.

    Ну да, в Обероне. В нормальных системах такой проблемы не будет.

    --
    С уважением,
    Alex Besogonov (alexy@izh.com)
    Posted via RSDN NNTP Server 1.9
    Sapienti sat!
    Re: Модульная загадка про константу
    От: Nickolay Ch  
    Дата: 01.07.05 12:47
    Оценка: 73 (5) +3 -1 :))) :)))
    Здравствуйте, Сергей Губанов, Вы писали БРЕД

    По вашим более ранним темам, я понял, что аргументов вы не воспринимаете, посему приводить их не буду
    Re[4]: Модульная загадка про константу
    От: Ракот  
    Дата: 01.07.05 13:37
    Оценка:
    Здравствуйте, Mr. None, Вы писали:

    MN>Здравствуйте, Сергей Губанов, Вы писали:


    СГ>>Здравствуйте, Cyberax, Вы писали:


    C>>>В нормальных языках (то есть в C/C++) такой проблемы нет — при

    C>>>модификации константы в h-файле просто все зависимое от нее
    C>>>перекомпилируется.

    СГ>>Эти языки не модульные. Нет модулей — нет проблем.


    C>>>В C# тоже нет проблемы — при изменении сборки меняется ее контрольная

    C>>>сумма, и все зависимое от нее будет перекомпилировано. При попытке
    C>>>совместить несовместимые сборки — получится exception.

    СГ>>Я только что привел пример где этого exception нет, зато преспокойно распечатывается "Module1.N = 10", в то время когда Module1.N = 20.


    MN>Вы не использовали strong-name для своей сборки, то есть не рассчитывали её контрольную сумму и не подписывали её — а, следовательно, это ваша сугубо личная проблема. Потому что такие сборки годятся только для написания тестов и отладочных версий приложений. Выпускаемая в свет сборка должна иметь строгое имя...


    Согласен. Только хочу добавить, что при подписывании сборки никакого процесса рассчета ее контрольной суммы не происходит (это нужно только студии). И не факт, что это может спасти. Если из сборки берется только константа, то такая сборка вовсе не нужна приложению и в процессе работы она не будет загружена. При этом приложение будет работать как раньше.

    Сергей Губанов, а зачем использовать константы, если, как правильно указал VladD2, есть readonly поля?
    Re[5]: Модульная загадка про константу
    От: Cyberax Марс  
    Дата: 01.07.05 13:45
    Оценка: +1
    Ракот wrote:

    > MN>Вы не использовали strong-name для своей сборки, то есть не

    > рассчитывали её контрольную сумму и не подписывали её — а,
    > следовательно, это ваша сугубо личная проблема. Потому что такие
    > сборки годятся только для написания тестов и отладочных версий
    > приложений. Выпускаемая в свет сборка должна иметь строгое имя...
    > Согласен. Только хочу добавить, что при подписывании сборки никакого
    > процесса рассчета ее контрольной суммы не происходит (это нужно только
    > студии).

    Происходит, рассчет контрольной суммы — это часть процесса подписывания.
    Подписанная либа получает GUID, по которому ее и находят остальные сборки.

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

    --
    С уважением,
    Alex Besogonov (alexy@izh.com)
    Posted via RSDN NNTP Server 1.9
    Sapienti sat!
    Re[6]: Модульная загадка про константу
    От: Oyster Украина https://github.com/devoyster
    Дата: 01.07.05 14:19
    Оценка:
    Здравствуйте, Cyberax, Вы писали:

    [... skipped ...]

    C>Происходит, рассчет контрольной суммы — это часть процесса подписывания.

    C>Подписанная либа получает GUID, по которому ее и находят остальные сборки.

    C>Подписанную сборку изменить нельзя, так что при изменении константы

    C>придется ее переподписать и сгенерировать новый GUID. Ну а от этого уже
    C>остальные сборки пересоберутся.

    А если я тем же ключом подпишу? Ведь тогда, по идее, строгое имя сборки не поменяется (если я преднамеренно не поменяю номер версии сборки, что я, конечно же, сделаю в случае её изменения ).
    Re[7]: Модульная загадка про константу
    От: Cyberax Марс  
    Дата: 01.07.05 14:25
    Оценка:
    Oyster wrote:

    > C>Подписанную сборку изменить нельзя, так что при изменении константы

    > C>придется ее переподписать и сгенерировать новый GUID. Ну а от этого уже
    > C>остальные сборки пересоберутся.
    > А если я тем же ключом подпишу? Ведь тогда, по идее, строгое имя
    > сборки не поменяется (если я преднамеренно не поменяю номер версии
    > сборки, что я, конечно же, сделаю в случае её изменения ).

    Ну если постараться, то можно что угодно сломать. Достаточно, чтобы
    сильное имя осталось тем же — этого можно добиться, если очень захотеть.

    --
    С уважением,
    Alex Besogonov (alexy@izh.com)
    Posted via RSDN NNTP Server 1.9
    Sapienti sat!
    Re[8]: Модульная загадка про константу
    От: Oyster Украина https://github.com/devoyster
    Дата: 01.07.05 15:15
    Оценка:
    Здравствуйте, Cyberax, Вы писали:

    C>Oyster wrote:


    >> C>Подписанную сборку изменить нельзя, так что при изменении константы

    >> C>придется ее переподписать и сгенерировать новый GUID. Ну а от этого уже
    >> C>остальные сборки пересоберутся.
    >> А если я тем же ключом подпишу? Ведь тогда, по идее, строгое имя
    >> сборки не поменяется (если я преднамеренно не поменяю номер версии
    >> сборки, что я, конечно же, сделаю в случае её изменения ).

    C>Ну если постараться, то можно что угодно сломать. Достаточно, чтобы

    C>сильное имя осталось тем же — этого можно добиться, если очень захотеть.

    Без приватного ключа? Нелегко это будет... А вот создателю сборки можно без проблем менять что угодно и когда угодно — у него ключ есть и поэтому он всегда может переподписать.
    Re[9]: Модульная загадка про константу
    От: Cyberax Марс  
    Дата: 01.07.05 15:23
    Оценка:
    Oyster wrote:

    > C>Ну если постараться, то можно что угодно сломать. Достаточно, чтобы

    > C>сильное имя осталось тем же — этого можно добиться, если очень захотеть.
    > Без приватного ключа? Нелегко это будет... А вот создателю сборки
    > можно без проблем менять что угодно и когда угодно — у него ключ есть
    > и поэтому он всегда может переподписать.

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

    --
    С уважением,
    Alex Besogonov (alexy@izh.com)
    Posted via RSDN NNTP Server 1.9
    Sapienti sat!
    Re[2]: Модульная загадка про константу
    От: Andrei N.Sobchuck Украина www.smalltalk.ru
    Дата: 01.07.05 15:25
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>Но, думаю я и так угадаю. Спецификации нужно читать. С целью увеличения быстродействия дотнет копирует (propagate) константы в применяемые модули. Другими словами константа — это ее значение.


    А как же хвалёный JIT?
    ... << RSDN@Home 1.1.4 beta 7 rev. 447>>
    Я ненавижу Hibernate
    Автор: Andrei N.Sobchuck
    Дата: 08.01.08
    !
    Re: Модульная загадка про константу
    От: andyJB  
    Дата: 01.07.05 17:06
    Оценка: 6 (1) +2
    Здравствуйте, Сергей Губанов, Вы писали:

    СГ>
  • Модульная загадка про константу

    СГ>[.skip.]

    Согласен, что значение константы должно быть частью метаинформации и анализироваться компилятором и рантаймом.
    Согласен, что в Обероне лучше, чем в C# и Java. Хотя, по-моему, совсем хорошо было бы, если бы эта проверка выполнялась непосредственно перед выполнением кода, использующего константу. Например, может быть атрибут у метода, содержащего вызов, "использую такую-то константу из такого-то модуля с таким-то значением". При загрузке кода метода атрибут можно было бы прочитать и убедиться, что значения констант совпадают, иначе кинуть exception.
    Про фатальность ошибок не согласен. На самом деле — оба типа могут быть как "фатальными", так и не "фатальными".
    С рассуждением про то, что константы нельзя использовать в модульных языках не согласен. Могу ещё одно такое же рассуждение толкнуть: допустим мы объявили в первом модуле метод, а во втором его вызвали. Компилятору нужно знать сигнатуру метода, чтобы сгенерировать код его вызова. Теперь добавим в метод параметр и перекомпилируем первый модуль, не компилируя второй. Запустим и, кто бы мог подумать, все фатально навернется при вызове! Выходит, в модульных системах должно быть запрещено использование методов. Чем не бред? Все потому, что выводы мало связаны с посылками, из которых сделаны. То же произошло и в Вашем рассуждении про константы.
  • Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.