替代(unsigned long long)演员而没有警告

时间:2014-01-07 04:04:01

标签: c casting warnings

我有一个宏需要能够接受任意整数或指针类型并将它们转换为unsigned long long。执行此操作的自然方式只是强制转换,并且可以正常工作,但是使用默认的GCC警告会产生“从指针转换为不同大小的整数”,我想避免这种情况。避免警告的自然方法是使用中间演员,如(unsigned long long)(uintptr_t)x,但在我的情况下不起作用,因为:

  1. 它将截断不适合uintptr_t
  2. 的整数输入
  3. 它会破坏已签名输入的正确转换,例如-1可能会变为0xffffffff而不是0xffffffffffffffff
  4. 如果我有一个表达式(可能使用?:运算符)可以区分指针和整数类型,我可以将其分解为两种情况并首先应用(uintptr_t)强制转换指针输入,但不是整数。关于一个可行的技巧的任何想法?

1 个答案:

答案 0 :(得分:1)

这似乎应该有效:

sizeof (1?(x):(unsigned long long)0) < sizeof (unsigned long long)
    ? (uintptr_t)(x)
    : (unsigned long long)(x)

例:

  1. x具有任何整数类型。然后,1?(x):(unsigned long long)0的类型为unsigned long long,因此会采用第二个分支,直接转换为unsigned long long
  2. x具有指针类型,指针类型小于unsigned long long。然后1?(x):(unsigned long long)0具有原始指针类型,并且第一个分支被执行,通过uintptr_t
  3. x具有指针类型,指针类型与unsigned long long的大小相同(或更大,但我认为不会发生)。然后是第二个分支,但无论如何都没有发出警告。
  4. 我不清楚GCC是否可以避免发出死代码警告(不会被采取的分支),但如果没有,可能__builtin_choose_expr是一个解决方案。