Здравствуйте!
В итоге вроде бы решил самым простым способом, без изысков
Хочу:
сonstexpr uintptr_t a = 140721923966320;
cout<<a;
Но: почему-то полагал, что не сработает, и что надо добавить суффикс типа (не "типа", а типа):
uintptr_t ptr = 12345ull;
Размер указателя зависит от платформы, поэтому решил:
#ifdef WIN32 /* например */
#define UPTR_SUFF ul
#elif defined(WIN64)
#define UPTR_SUFF ull
#endif
#define DECLARE_CONST_ADDR_SUFFIX_HELPER(suff) suff
// не работает
#define DECLARE_CONST_ADDR(addr, suff) addr ## DECLARE_CONST_ADDR_SUFFIX_HELPER(suff)
// так тоже
#define DECLARE_CONST_ADDR(addr, suff) addr ## suff
Как быть?
В итоге-то вроде работает по самому простому пути, и в случае чего проще переопределить сам макрос DECLARE_CONST_ADDR или есть вариант задать с помощью UPTR_SUFF?
А если слева будет какой-то объект, который хочет другое, например short unsigned?
Здравствуйте, Marty, Вы писали:
M>В итоге вроде бы решил самым простым способом, без изысков
M>Хочу:
M>сonstexpr uintptr_t a = 140721923966320;
M>cout<<a;
M>
И что мешает писать прямо вот так, как выше написано?
M>Но: почему-то полагал, что не сработает
Полагал? То есть сейчас так не полагаешь? Ну и правильно.
M>Размер указателя зависит от платформы, поэтому решил:
M>M>#ifdef WIN32 /* например */
M> #define UPTR_SUFF ul
M>#elif defined(WIN64)
M> #define UPTR_SUFF ull
M>#endif
M>#define DECLARE_CONST_ADDR_SUFFIX_HELPER(suff) suff
M>// не работает
M>#define DECLARE_CONST_ADDR(addr, suff) addr ## DECLARE_CONST_ADDR_SUFFIX_HELPER(suff)
M>// так тоже
M>#define DECLARE_CONST_ADDR(addr, suff) addr ## suff
M>
Во-первых, все загоны с суффиксами ul и ull тут не нужны. Совсем не нужны.
Во-вторых, такие макросы пишутся так:
#define DECLARE_CONST_ADDR_HELPER(addr, suff) addr ## suff
#define DECLARE_CONST_ADDR(addr, suff) DECLARE_CONST_ADDR_HELPER(addr, suff)
// DECLARE_CONST_ADDR(123, UPTR_SUFF) раскроется в 123ul, если UPTR_SUFF определён как ul
В-третьих, не вздумай их использовать, потому что пункт первый :)
Суффиксы l и ll задают
ограничение снизу на тип:
auto i = 1; // decltype(i) -> int
auto j = 2l; // decltype(j) -> long
auto k = 3ll; // decltype(k) -> long long
Тебе же уже известно какой тим нужно получить — uintptr_t. Значит никакие дополнительные ограничения не нужны.
Важно только знаковый тип или нет. То есть суффикс u для uintptr_t и никакого для intptr_t.
M>Как быть?
Что именно надо-то? Получить uintptr_t с таким же значением как и в числовой записи ? Пиши
uintptr_t{42u}
Ну или через свои макросы как-то так:
#define DECLARE_CONST_ADDR(addr) uintptr_t{addr ## u}
Cуффикс
u покажет что нужно беззнаковое число (формально это важно в случаях, когда значение представимо в самом широком беззнаковом типе, но не представимо в самом широком знаковом типе). А запись
uintptr_t{x} (в отличии от например
uintptr_t(x)) скажет компилятору ругаться, если число не влезает в тип (типичная ситуация, когда платформа поддерживает 64-х битные целые числа, но использует 32-х битные указатели).
Если же вопрос сужения не волнует, то достаточно написать
#define DECLARE_CONST_ADDR(addr) addr :)
M>А если слева будет какой-то объект, который хочет другое, например short unsigned?
Вот это дельный вопрос. В С++ отсутствуют compound literals, которые есть в C. А по грамматике в explicit type conversion можно использовать только одно слово (а в unsigned short их два).
Поэтому подобное можно сделать только через алиас типа:
(unsinged short){30} // нельзя в C++
unsinged short{30} // нельзя в C++
using unsinged_short = unsigned short;
unsinged_short{30}; // можно
(unsigned short)(30) // тоже можно, не нет защиты от сужения, если вместо 30 окажется какое-нибудь огромное число
Но обычно подобные конструкции не нужны. Например, потому что есть переменные и константы:
constexpr unsigned short a{30};
Здравствуйте, watchmaker, Вы писали:
В MSVC компилируется.
Записать в баг или в фичу ?
int main()
{
constexpr auto A = unsigned short{10};
}
Здравствуйте, Marty, Вы писали:
M>В итоге вроде бы решил самым простым способом, без изысков
M>Хочу:
M>M>сonstexpr uintptr_t a = 140721923966320;
M>cout<<a;
M>
В новых стандартах можно писать с изысками:
constexpr uintptr_t a = 140'721'923'966'320;
Здравствуйте, Sergey_BG, Вы писали:
S_B>Здравствуйте, _NN_, Вы писали:
_NN>>В MSVC компилируется.
S_B>Интересно это их специальная политика, чтоб ухудшить переносимость, или же они об удобстве беспокоятся.
Или предсказывают светлое будущее как было с
typename
Здравствуйте, watchmaker, Вы писали:
Спасибо за ликбез