Мне надо вычислить значение выравнивания. То есть, есть массив байт и есть некий указатель внутри него, который может быть невыровненным, иметь, скажем, абстрактное значение 13. Допустим, мне надо выровнять его до 16 всегда в сторону увеличения. В данном случае — прибавить 3. Я делаю это так:
Где alignment=16 в данном случае.
Вопрос в том, как преобразовать ptr к unsigned без предупреждений компилятора "for the possible 64-bit pointer to 32-bit unsigned conversion", причем надо сделать это без применения __int64 и прочих компиляторо-зависимых типов. Ясно, что если указатель 64 бита, а unsigned — 32, то и фиг с ней со старшей частью, на вычисление выравнивания она никак не влияет.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, McSeem2, Вы писали:
MS>Мне надо вычислить значение выравнивания. То есть, есть массив байт и есть некий указатель внутри него, который может быть невыровненным, иметь, скажем, абстрактное значение 13. Допустим, мне надо выровнять его до 16 всегда в сторону увеличения. В данном случае — прибавить 3. Я делаю это так: MS>
MS>Где alignment=16 в данном случае. MS>Вопрос в том, как преобразовать ptr к unsigned без предупреждений компилятора "for the possible 64-bit pointer to 32-bit unsigned conversion", причем надо сделать это без применения __int64 и прочих компиляторо-зависимых типов. Ясно, что если указатель 64 бита, а unsigned — 32, то и фиг с ней со старшей частью, на вычисление выравнивания она никак не влияет.
Здравствуйте, WolfHound, Вы писали:
WH>Гм. А size_t поюзать не пробовал?
А можно как-нибудь без size_t, а только базовыми типами обойтись? И вообще, странно, если size_t 32 бита, должно быть в точности такое же предупреждение, а если 64 — то на фиг мне такая size_t не уперлась на 32-битной платформе. Чего-то там MS компилятор мухлюет насчет size_t
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, McSeem2, Вы писали:
MS>Здравствуйте, WolfHound, Вы писали:
WH>>Гм. А size_t поюзать не пробовал?
MS>А можно как-нибудь без size_t, а только базовыми типами обойтись? И вообще, странно, если size_t 32 бита, должно быть в точности такое же предупреждение, а если 64 — то на фиг мне такая size_t не уперлась на 32-битной платформе. Чего-то там MS компилятор мухлюет насчет size_t
На 64-битной платформе size_t будет 64-битным, ведь size_t по сути беззнаковое целое, соответствующее указателю на данные (а ptrdiff_t — знаковое).
Кстати, если заложиться на то что выравнивание является степенью двойки, то можно подстроить указатель экономнее:
Здравствуйте, folk, Вы писали:
F>На 64-битной платформе size_t будет 64-битным, ведь size_t по сути беззнаковое целое, соответствующее указателю на данные (а ptrdiff_t — знаковое).
Нет, вопрос в том, почему на 32-х битовых платформах MS компилятор ругается на unsigned и не ругается на size_t?По идее компилятор ничего не должен знать о size_t, это не есть базовый тип C++, он должнен быть определен синонимом через typedef. А получается что либо компилятор знает, либо size_t определен как 64-битный, что есть маздай.
F>Кстати, если заложиться на то что выравнивание является степенью двойки, то можно подстроить указатель экономнее:
Здравствуйте, McSeem2, Вы писали:
F>>На 64-битной платформе size_t будет 64-битным, ведь size_t по сути беззнаковое целое, соответствующее указателю на данные (а ptrdiff_t — знаковое).
MS>Нет, вопрос в том, почему на 32-х битовых платформах MS компилятор ругается на unsigned и не ругается на size_t?По идее компилятор ничего не должен знать о size_t, это не есть базовый тип C++, он должнен быть определен синонимом через typedef. А получается что либо компилятор знает, либо size_t определен как 64-битный, что есть маздай.
Имхо наоборот, если бы компилятор не догадывался о 64-битном size_t при 64-битном void*, то был бы маздай.
И еще мазадай в том что sizeof(size_t) > sizeof(long).
Здравствуйте, McSeem2, Вы писали:
MS>А можно как-нибудь без size_t, а только базовыми типами обойтись? И вообще, странно, если size_t 32 бита, должно быть в точности такое же предупреждение, а если 64 — то на фиг мне такая size_t не уперлась на 32-битной платформе. Чего-то там MS компилятор мухлюет насчет size_t
Этот варнинг связан с тем что если вой код скомпиляровать под 64х битную платформу то он перестанет работать.
Как уже сказали size_t 32х битный на 32х битной платформе и 64х битный на 64х битной платформе. Компилятор об этом знает и и по этому не дает варнинг.
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, McSeem2, Вы писали:
MS>Здравствуйте, folk, Вы писали:
F>>На 64-битной платформе size_t будет 64-битным, ведь size_t по сути беззнаковое целое, соответствующее указателю на данные (а ptrdiff_t — знаковое).
MS>Нет, вопрос в том, почему на 32-х битовых платформах MS компилятор ругается на unsigned и не ругается на size_t?По идее компилятор ничего не должен знать о size_t,
Знает, знает. В наше время компиляторы умнее людей
Microsoft Specific
type __w64 identifier
where:
type
One of the three types that might cause problems in code being ported from a 32-bit to a 64-bit compiler: int, long, or a pointer.
identifier
The identifier for the variable you are creating.
Remarks
The __w64 keyword lets you mark variables, such that when you compile with /Wp64 the compiler will report any warnings that would be reported if you were compiling with a 64-bit compiler.
Any typedef that has __w64 on it must be 32 bits on x86 and 64 bits on ia64.
The __w64 modifier should be specified on any typedefs that change size between 32 bit and 64 bit platforms. For any such type, __w64 should appear only on the 32-bit definition of the typedef. For example:
#ifdef _WIN64
typedef unsigned __int64 size_t;
#else
typedef _W64 unsigned int size_t;
#endif
__w64 is ignored if the compilation does not use /Wp64.
Example
// __w64.cpp
// compile with: /W3 /Wp64
typedef int Int_32;
#ifdef _WIN64
typedef __int64 Int_Native;
#else
typedef int __w64 Int_Native;
#endif
int main()
{
Int_32 i0 = 5;
Int_Native i1 = 10;
i0 = i1; // C4244 64-bit int assigned to 32-bit int
// char __w64 c; error, cannot use __w64 on char
}
END Microsoft Specific
ЗЫ.
А для чего нужен тег [ msdn ] ? Я им пытался воспользоваться...
Правильно работающая программа — просто частный случай Undefined Behavior
MS>Не катит. Слова "byte order" ни о чем не говорят?
Говорят и очень много. на x86 порядок обратный, поэтому unsigned *u_ptr = (unsigned *)&ptr есть указатель на младший байт, на младшее слово, и на младшее двойное слово.
Здравствуйте, Alex Reyst, Вы писали:
AR>Здравствуйте, _Winnie, Вы писали:
_W>>А для чего нужен тег [ msdn ] ? Я им пытался воспользоваться...
AR>Автоматическое формирование URL запроса к MSDN с поиском заключенной в тег фразы.
Здравствуйте, McSeem2, Вы писали:
MS>Здравствуйте, folk, Вы писали:
F>>На 64-битной платформе size_t будет 64-битным, ведь size_t по сути беззнаковое целое, соответствующее указателю на данные (а ptrdiff_t — знаковое).
MS>Нет, вопрос в том, почему на 32-х битовых платформах MS компилятор ругается на unsigned и не ругается на size_t?По идее компилятор ничего не должен знать о size_t, это не есть базовый тип C++, он должнен быть определен синонимом через typedef. А получается что либо компилятор знает, либо size_t определен как 64-битный, что есть маздай.
size_t такой же стандартный тип как и unsigned. А то что он у VC объявлен как typedef ни о чем не говорит. А ругается он не потому, что у тебя что-то не так, а что проблемы возникнут при компиляции этого кода под 64-битной платформой.
Здравствуйте, Aera, Вы писали:
A>size_t такой же стандартный тип как и unsigned. А то что он у VC объявлен как typedef ни о чем не говорит. А ругается он не потому, что у тебя что-то не так, а что проблемы возникнут при компиляции этого кода под 64-битной платформой.
size_t не является базовым типом данных C++. Period.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, JakeS, Вы писали:
MS>>Не катит. Слова "byte order" ни о чем не говорят?
JS>Говорят и очень много. на x86 порядок обратный, поэтому unsigned *u_ptr = (unsigned *)&ptr есть указатель на младший байт, на младшее слово, и на младшее двойное слово.
Не Интелом Единым, как говорится...
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, McSeem2, Вы писали:
MS>Мне надо вычислить значение выравнивания. То есть, есть массив байт и есть некий указатель внутри него, который может быть невыровненным, иметь, скажем, абстрактное значение 13. Допустим, мне надо выровнять его до 16 всегда в сторону увеличения. В данном случае — прибавить 3. Я делаю это так:
А если посмотреть с другой стороны. Вам нужно выравнивание по последним четырем битам. Что мешает сделать следующее:
template <class T> T align(T value, unsigned char bitsCount) {
assert(sizeof T <= bitsCount);
T alignment = 0;
for (unsigned char i = 0; i < bitsCount; ++i) {
alignment <<= 1;
alignment |= 1;
}
T piece = value & alignment;
T result = value >> bitsCount;
if (piece != 0) {
++result; //здесь может быть другая функция, смотря как конкретно вам нужно выравнивать
}
return result << bitsCount;
}