У меня есть макрос, который должен иметь возможность принимать произвольные целые числа или типы указателей и преобразовывать их в unsigned long long
. Естественный способ сделать это - просто бросить, и это работает, но с предупреждениями GCC по умолчанию он дает «отбрасывание от указателя до целого разного размера», и я бы хотел этого избежать. Естественный способ избежать предупреждений является с промежуточным гипсе, как в (unsigned long long)(uintptr_t)x
, но это не работает в моем случае, потому что:Альтернатива без знака без знака
- Это усечения целых входов, которые не помещаются в
uintptr_t
. - Он нарушит правильное преобразование подписанных входов, например. -1 может стать
0xffffffff
вместо0xffffffffffffffff
.
Если бы я имел выражение (возможно, делая фантазию использование оператора ?:
), которые могли бы отличить указатель от целочисленных типов, я мог бы разбить его в двух случаев и применить (uintptr_t)
бросок первым для входов указателя, но не для целочисленные. Какие-нибудь идеи об уловке, которые будут работать?
(поистине ужасно, только для безумных): '_Generic' с футляром для каждого целочисленного типа. –
@ StephenCanon: Справедливости ради, вы можете сделать это немного менее страшным, применив операцию, которая выполняет целые рекламные акции, но это также безопасно применять к указателям, тем самым устраняя все те, у которых более низкий ранг, чем 'int'. '1? X: 0' должен работать. –
Или даже лучше: примените '1? X: (uintmax_t) 0', принудительно применяя любой целочисленный тип к' uintmax_t' для целей '_Generic', оставив типы указателей нетронутыми. К сожалению, для этого все еще требуется поддержка C11, которая не получила широкого распространения. –