【问题标题】:Explicit cast of pointer to long long指向 long long 的指针的显式转换
【发布时间】:2016-10-18 19:31:10
【问题描述】:

我需要将指针转换为 long long,并且希望以 gcc 不会抱怨 32 位或 64 位架构关于将指针转换为不同大小的 int 的方式执行此操作。在任何人问之前,是的,我知道我在做什么,我知道我在做什么——我的具体用例是想通过网络发送一个堆栈跟踪(指针本身就是这里的主题),当发生应用程序错误,因此无法保证发送方和接收方将具有相同的字长。因此,我构建了一个包含消息数据的结构,其中包含一个“unsigned long long”值数组(保证最小 64 位)来保存指针。是的,我知道“long long”不是保证 只有 64 位的,但是我用于源和目标的所有编译器都将它实现为 64-位。因为带有结构的标头(和源)将用于两种架构,“uintptr_t”似乎不是一个可行的解决方案(因为根据 stdint.h 中的定义,它的大小取决于架构)。

我曾想过用匿名工会变得棘手,但这对我来说有点太骇人听闻了...我希望在 C99 中有一种方法可以使用双重施法或其他方法来做到这一点(因为匿名工会没有) t 标准直到 C11)。

编辑:

typedef struct error_msg_t {
  int msgid;
  int len;
  pid_t pid;
  int si_code;
  int signum;
  int errno;
  unsigned long long stack[20];
  char err_msg[];
} error_msg_t;
...
void **stack;
...
msg.msgid = ERROR_MSG;
msg.len = sizeof(error_msg_t) + strlen(err_msg) + 1);
msg.pid = getpid();
...
for (i=0; i<stack_depth; i++)
  msg.stack[i] = (unsigned long long)stack[i];

关于强制转换为不同大小的整数的警告(在 32 位编译中)出现在最后一行。

【问题讨论】:

  • uint64_t 会是更好的选择。
  • (uint64_t)(uintptr_t)stack[1] 是否删除警告?
  • uint_least64_t 会更好,因为uint64_t 是可选类型。
  • 您是否可以考虑发送printf("%p", ptr) 的输出而不是整数值?
  • uint_least64_t 更糟。问题是关于精确 64 位的整数,并且仅限于支持它的平台。平台报错是有好处的,不能轻易支持。

标签: c pointers


【解决方案1】:

您最好的选择可能是双重转换以向编译器说明您想要做什么 (as suggested by Max)。

我建议将其包装成一个宏,以便从宏名称中清楚代码意图。

#define PTR_TO_UINT64(x) (uint64_t)(uintptr_t)(x)

【讨论】:

  • 不要宏化你能做的事情static inline
  • @Rhymoid:我觉得宏在这里是一个更好的选择,因为虽然您希望代码可读,但您仍然想传达一种概念,即正在发生一些时髦的事情。
猜你喜欢
  • 1970-01-01
  • 2017-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-30
相关资源
最近更新 更多