【问题标题】:Can you not call a preprocessor macro from a specific namespace the same way you call a function from a specific namespace?您不能像从特定命名空间调用函数一样从特定命名空间调用预处理器宏吗?
【发布时间】:2021-01-31 06:48:20
【问题描述】:

好的,所以我正在编写一些嵌入式代码以在 msp430 启动板上运行,我试图将引脚切换为高电平,当我开始尝试使用头文件中的一个宏时遇到了问题,该宏是也在 main.cpp 文件的特定命名空间中。我假设我可以使用相同的约定来调用该命名空间中的函数来调用宏?在我声明使用命名空间而不是我想要的 msp430:: 之前,代码不会编译,因为我在头文件中有 3 个不同的命名空间。没有声明使用命名空间就没有办法做到这一点吗?我也可以使用命名空间中的变量来做到这一点,所以我看不到使用简单的宏 def 看不到的东西。

expected unqualified-id before token

//section from the header file
#define P4DIR_m  *((unsigned int volatile*)0x0224u)
#define P8OUT_m  *((unsigned int volatile*)0x0262u)
#define P8DIR_m  *((unsigned int volatile*)0x0264u)
#define P1DIR_m  *((unsigned int volatile*)0x0204u)
#define LEDOUT_m *((unsigned int volatile*)0x0202u) //this line gives the error

 
//----------main.cpp

//code that called the macro orginally
msp430::LEDOUT_m |= 0x01; //this failed 

//new code
using namespace msp430;

LEDOUT_m |= 0x01; // this worked but I don't want to do this as I have other namespaces

ide snapshot with code

【问题讨论】:

  • 第一。不要发布图片,发布整个消息。其次,我们不知道这是真正的编译器错误,还是第三方插件或工具生成的某些错误,而这些错误确实不是来自编译器。
  • 很可能是使用宏的地方造成的。 (您可以将宏扩展定义为几乎任何废话;在扩展之前它不是错误。)
  • @molbdnilo 这是正确的,如果我注释掉宏调用代码,错误就会消失,所以我想我错误地认为你可以从特定命名空间调用定义,就像你调用函数一样一个特定的命名空间??我用了``` msp430::LEDOUT_m |= 0x01; //在main.cpp中设置一个引脚高
  • constexpr 是 C++11 的类型安全的命名空间宏替代方案。不幸的是,该标准明确规定您不能将 constexpr 指针指向文字值(例如易失性地址)。 This answer 解释了原因,并推荐使用 GNU 扩展 __builtin_constant_p 作为解决方法(如果您可以使用)。
  • @mac using namespace msp430; 对宏完全没有影响,没有它LEDOUT_m |= 0x01; 也可以工作。宏不属于命名空间。预处理是“真正”编译开始之前的一个单独阶段。

标签: c++ c++11 pointers embedded


【解决方案1】:

不,宏不知道命名空间。尽可能避免使用宏。在这里你可能可以做类似的事情

namespace msp430 {
// inline requires C++17, allowing you to put this as is in the header:
inline auto& LEDOUT_m = *reinterpret_cast<unsigned int volatile*>(0x0202u);
}

// A trick I saw in a talk by Hana Dusíková that she uses for debugging her CTRE library: https://github.com/hanickadot/compile-time-regular-expressions
template <typename T> struct report_type_name;

int main() {
    msp430::LEDOUT_m |= 0x01; // Can access namespace-qualified
    namespace NS =  msp430;
    NS::LEDOUT_m = 0x0; // Can use ns aliases 'cause why not.
    using namespace msp430;
    LEDOUT_m |= 0x02; // Can use using namespace too.
    // Uncomment the next line to check that 
    // the type really is volatile unsigned int&:
    // report_type_name<decltype(LEDOUT_m)>{};
}

https://godbolt.org/z/1j7e3f

【讨论】:

    猜你喜欢
    • 2017-04-12
    • 2011-01-11
    • 1970-01-01
    • 2016-10-28
    • 2012-01-21
    • 1970-01-01
    • 2012-01-20
    • 2021-04-15
    • 1970-01-01
    相关资源
    最近更新 更多