
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.9.169] |
![]() |
|
Сообщ.
#1
,
|
|
|
Есть свой старый код:
![]() ![]() void func( unsigned long *a) { ... ((unsigned short*)a)++; // здесь выдаёт "Lvalue required" ... } |
![]() |
Сообщ.
#2
,
|
|
Потому что операция преобразования unsigned long* в unsigned short* создаёт новый временный объект, не связанный с исходным a. Применение операции постинкремента к временному объекту бессмысленна, т.к. её результатом является новый временный объект с ещё не изменённым значением, а инкремент выполняется на предыдущем объекте, который невозможно никак использовать, на то он и временный.
Если раньше компилировалось, значит компилятор нарушал Стандарт. Возможно, он не создавал временного объекта при касте типа указателя. Возможно, он плевать котел на бессмысленность постинкремента на rvalue вместо lvalue. В любом случае код и ранее был неправилен, а как правильно, надо спросить у его автора. Возможно он имел в виду ![]() ![]() ++*(unsigned short**)&a; |
Сообщ.
#3
,
|
|
|
1. Не знал, что (unsigned short*) - операция. Считал, что это лишь способ рассказать компилятору, что переменная=указатель указывает на нечто иное, и только то.
2. Да, в принципе ваша строка делает то, что и требовалось, но читаемость, конечно, сильно пострадает от этого. ![]() А всего лишь хотелось изменить=подвинуть на 2 [байта] указатель... ![]() |
Сообщ.
#4
,
|
|
|
Цитата Славян @ А всего лишь хотелось изменить=подвинуть на 2 [байта] указатель... ![]() Так подвинь: ![]() ![]() 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; } |
![]() |
Сообщ.
#5
,
|
|
Цитата Славян @ В таком случае unsiged long* либо был невыровненным, либо стал таковым. А всего лишь хотелось изменить=подвинуть на 2 [байта] указатель... |
Сообщ.
#6
,
|
|
|
Цитата ЫукпШ @ Тут заводится доп. переменная, а хочется компактно, изящно и лаконично, как было раньше... Так подвинь: ... ![]() Цитата Qraizer @ Выравнивание - "головная" боль машины/архитектуры. Считаю идеологически неправильным переносить её на компилятор с последующим неким переносом её на программиста. В таком случае unsiged long* либо был невыровненным, либо стал таковым. ![]() |
Сообщ.
#7
,
|
|
|
Цитата Славян @ А всего лишь хотелось изменить=подвинуть на 2 [байта] указатель... ![]() ![]() a = (unsigned long *)(void *)((unsigned short *)a + 1); |
Сообщ.
#8
,
|
|
|
Да, можно и так. Но метод Qraizer'а всё же несколько краше.
![]() |
Сообщ.
#9
,
|
|
|
Цитата Dushevny @ Цитата Славян @ А всего лишь хотелось изменить=подвинуть на 2 [байта] указатель... ![]() ![]() a = (unsigned long *)(void *)((unsigned short *)a + 1); Если речь идёт об этом, тогда лучше рассмотреть правильность программы вообще. Увеличить на 2 байта указатель unsigned long * - это значит выходить за границы переменной unsigned long. (Увеличить unsigned short * - это ещё объяснимо.) --- Подозрительно выглядит сам алгоритм и ругательства компилятора выглядят совершенно к месту. Хотя он это делает по другому поводу. |
![]() |
Сообщ.
#10
,
|
|
Цитата Славян @ Первая фраза абсолютно верна. Компилятор всегда обеспечивает правильное выравнивание для данных ему структур данных. Вторая прямо противоречит первой. Код явным образом насильно заставляет компилятор отойти от его правил. Посему сваливать на него ответственность за нарушение выравнивания... очень мягко говоря, некорректно. Если тебя вытолкнут на красный в спину, виноват будешь ты, да? Выравнивание - "головная" боль машины/архитектуры. Считаю идеологически неправильным переносить её на компилятор с последующим неким переносом её на программиста. |