0

Ok so I am working on some embedded code to go on a msp430 launch pad, I was trying to toggle a pin high and I ran into an issue when I began trying to use one of the macros in the header file which was also in a specific namespace in the main.cpp file. I assumed I could use the same convention as say to call a function in that namespace for call a macro? The code would not compile until I declared using namespace, instead of msp430:: like I wanted since I have 3 different namespaces in the header file. is there not a way to do this without declaring the using namespace? I can do it with variables from a namespace as well so I don't see what I could not with a simple macro 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

mac
  • 3
  • 2
  • First. don't post images, post the entire message. Second, we don't know if that's a real compiler error, or some error generated by a third-party plugin or tool that really doesn't come from the compiler. – PaulMcKenzie Oct 16 '20 at 18:25
  • It's very likely caused in the place where the macro is used. (You can define a macro expansion as pretty much any nonsense; it's not an error until it's expanded.) – molbdnilo Oct 16 '20 at 18:31
  • @molbdnilo that is correct if I comment out the macro calling code the error goes away so I guess I was wrong in thinking you could call a definition from a specific namespace that same way you call a function from a specific namespace?? I used ``` msp430::LEDOUT_m |= 0x01; //to set a pin high in the main.cpp – mac Oct 16 '20 at 19:25
  • `constexpr` is the type-safe namespace-able macro alternative for C++11. Unfortunately, the standard explicitly states you can't have a `constexpr` pointer to a literal value (e.g. volatile address). [This answer](https://stackoverflow.com/a/10376574/1863938) explains why, and recommends the GNU extension `__builtin_constant_p` as a workaround if it's available to you. – parktomatomi Oct 16 '20 at 20:48
  • @mac The `using namespace msp430;` has no effect on the macro at all, and `LEDOUT_m |= 0x01;` will work without it. Macros don't belong to namespaces. Preprocessing is a separate phase before the "real" compilation starts. – molbdnilo Oct 16 '20 at 22:11

1 Answers1

1

No, macros don’t know about namespaces. Try to avoid macros whenever possible. Here you can probably do something like

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

Ben
  • 9,184
  • 1
  • 43
  • 56