C++宏代码 - 显式整数(任何大小)转换为指针类型

C++ Macro Code - Explicit integer (of any size) conversion to a pointer type

本文关键字:转换 类型 指针 任何大 宏代码 整数 C++      更新时间:2023-10-16

问题:我正在与具有预先存在的宏的 AVR 代码接口......

#define pgm_read_float_near(address_short) foo

它用于将uint16_t值作为指针,获取它,然后返回float值。我使用的是具有平面地址空间的 x86 处理器,我只需要这个宏来尊重指针。我的目标是在取消引用之前从uint16_t非常明确地转换为float *

当前解决方案:

#define pgm_read_float_near(address_short) *reinterpret_cast<float *>(reinterpret_cast<void *>(NULL) | static_cast<uint16_t>(address_short))

我试图做什么..

  1. static_cast提供给宏的任何变量(不是类型安全(作为我期待的uint16_t
  2. OR该值,并带有"NULL指针",以"干净利落地"将uint16_t扩展到 uint32_t
  3. reinterpret_cast OR的结果回到float *
  4. 最后,尊重获取float值的float *

问题:

  1. 我忘记了任何步骤吗?
  2. 我是否在做任何不必要的步骤,为什么?

注意:在你说"宏太可怕了!我别无选择,我正在现有的框架中工作......

由于您使用的是C++,因此我建议使用C++模板:

#include <stdio.h>
#include <stdint.h>
template<class Ty>
float *explicit_cast(Ty t) {
    return 2;
}
template<>
float *explicit_cast<uint16_t>(uint16_t t) {
    return reinterpret_cast<float *>(t);
}
#define pgm_read_float_near(address_short) explicit_cast(address_short)
void t8() {
    uint8_t f8 = 2;
    pgm_read_float_near(f8);
}
void t16() {
    uint16_t f16 = 2;
    pgm_read_float_near(f16);
}
void t32() {
    uint32_t f32 = 2;
    pgm_read_float_near(f32);
}

通过编译程序,您可以看到以下输出:

$ g++ cast.cpp -c
cast.cpp: In instantiation of ‘float* explicit_cast(Ty) [with Ty = unsigned char]’:
cast.cpp:18:5:   required from here
cast.cpp:6:12: error: invalid conversion from ‘int’ to ‘float*’ [-fpermissive]
cast.cpp: In instantiation of ‘float* explicit_cast(Ty) [with Ty = unsigned int]’:
cast.cpp:28:5:   required from here
cast.cpp:6:12: error: invalid conversion from ‘int’ to ‘float*’ [-fpermissive]

从其他类型的强制转换将引入编译错误。原理是我们可以使用该模板来区分uint16_t和其他类型。