На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
  
> Ошибка в изменении адреса
    Есть свой старый код:
    ExpandedWrap disabled
      void func( unsigned long *a)
      {
          ...
          ((unsigned short*)a)++; // здесь выдаёт "Lvalue required"
          ...
      }
    Раньше (в какой-то BCB2006 или около того) компилировалось, сейчас (RAD-XE8) выдаёт ошибку E2277. Почему? Как поправить?
      Потому что операция преобразования unsigned long* в unsigned short* создаёт новый временный объект, не связанный с исходным a. Применение операции постинкремента к временному объекту бессмысленна, т.к. её результатом является новый временный объект с ещё не изменённым значением, а инкремент выполняется на предыдущем объекте, который невозможно никак использовать, на то он и временный.
      Если раньше компилировалось, значит компилятор нарушал Стандарт. Возможно, он не создавал временного объекта при касте типа указателя. Возможно, он плевать котел на бессмысленность постинкремента на rvalue вместо lvalue. В любом случае код и ранее был неправилен, а как правильно, надо спросить у его автора. Возможно он имел в виду
      ExpandedWrap disabled
        ++*(unsigned short**)&a;
      что всё равно не сильно отличается от бреда.
        1. Не знал, что (unsigned short*) - операция. Считал, что это лишь способ рассказать компилятору, что переменная=указатель указывает на нечто иное, и только то.
        2. Да, в принципе ваша строка делает то, что и требовалось, но читаемость, конечно, сильно пострадает от этого. :yes-sad:

        А всего лишь хотелось изменить=подвинуть на 2 [байта] указатель... :wall:
          Цитата Славян @
          А всего лишь хотелось изменить=подвинуть на 2 [байта] указатель... :wall:

          Так подвинь:
          ExpandedWrap disabled
            void func(unsigned long *a)
            {
            //       ...
                 unsigned short aa = *((unsigned short*)a+1);
            //
                 unsigned short* pa = ((unsigned short*)a+1);
            //       ...
                 unsigned short* pa = (unsigned short*)a;
                 pa++;
                 unsigned short aa = *pa;
            }
            Цитата Славян @
            А всего лишь хотелось изменить=подвинуть на 2 [байта] указатель...
            В таком случае unsiged long* либо был невыровненным, либо стал таковым.
              Цитата ЫукпШ @
              Так подвинь:
              ...
              Тут заводится доп. переменная, а хочется компактно, изящно и лаконично, как было раньше... :'(

              Цитата Qraizer @
              В таком случае unsiged long* либо был невыровненным, либо стал таковым.
              Выравнивание - "головная" боль машины/архитектуры. Считаю идеологически неправильным переносить её на компилятор с последующим неким переносом её на программиста. :oops:
                Цитата Славян @
                А всего лишь хотелось изменить=подвинуть на 2 [байта] указатель...

                ExpandedWrap disabled
                  a = (unsigned long *)(void *)((unsigned short *)a + 1);
                Приведение к (void *) - чтобы подавить жалобы компилятора на невыровненность получившегося указателя..
                  Да, можно и так. Но метод Qraizer'а всё же несколько краше. :blush:
                    Цитата Dushevny @
                    Цитата Славян @
                    А всего лишь хотелось изменить=подвинуть на 2 [байта] указатель...

                    ExpandedWrap disabled
                      a = (unsigned long *)(void *)((unsigned short *)a + 1);
                    Приведение к (void *) - чтобы подавить жалобы компилятора на невыровненность получившегося указателя..

                    Если речь идёт об этом, тогда лучше рассмотреть
                    правильность программы вообще.
                    Увеличить на 2 байта указатель unsigned long * - это
                    значит выходить за границы переменной unsigned long.
                    (Увеличить unsigned short * - это ещё объяснимо.)
                    ---
                    Подозрительно выглядит сам алгоритм и ругательства
                    компилятора выглядят совершенно к месту.
                    Хотя он это делает по другому поводу.
                    Сообщение отредактировано: ЫукпШ -
                      Цитата Славян @
                      Выравнивание - "головная" боль машины/архитектуры. Считаю идеологически неправильным переносить её на компилятор с последующим неким переносом её на программиста.
                      Первая фраза абсолютно верна. Компилятор всегда обеспечивает правильное выравнивание для данных ему структур данных. Вторая прямо противоречит первой. Код явным образом насильно заставляет компилятор отойти от его правил. Посему сваливать на него ответственность за нарушение выравнивания... очень мягко говоря, некорректно. Если тебя вытолкнут на красный в спину, виноват будешь ты, да?
                      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                      0 пользователей:


                      Рейтинг@Mail.ru
                      [ Script execution time: 0,0507 ]   [ 17 queries used ]   [ Generated: 20.04.24, 04:47 GMT ]