Problem building C++ projects with SDK 2.6.0?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem building C++ projects with SDK 2.6.0?

Jump to solution
4,683 Views
1234567890
Contributor IV

Hi,

creating a standard C++ project with the wizard on 11.0 build with a lot of strange errors. With SDK 2.5.0 everything is fine. "My" SDK is attached.

Simply choose new project, lpc845breakout board, the attached 2.6.0 SDK, empty board files, C++, newlibnano (semihost). Then try build it.

Labels (1)
1 Solution
3,950 Views
1234567890
Contributor IV

Now the (very, very tiny) fix works as expected, and that only 2 years later...

View solution in original post

13 Replies
3,979 Views
diego_charles
NXP TechSupport
NXP TechSupport

Hi @1234567890  and @dmarks_ls 

Many thanks for your reports!

Please take a look at the  LPC845 BRK SDK ver. 2.9.0.  We changed the following lines:

#define CLK_MUX_DEFINE(reg, mux) (((offsetof(SYSCON_Type, reg) & 0xFFU) << 8U) | ((mux)&0xFFU))

#define CLK_DIV_DEFINE(reg) (((uint32_t)offsetof(SYSCON_Type, reg)) & 0xFFFU)

Now a CPP project should build without problems.

If somebody catches a problem in another SDK release, please let us know.

Yours ,

Diego

0 Kudos
Reply
4,294 Views
dmarks_ls
Senior Contributor II

NXP,

Still waiting for you to acknowledge this issue in your software.  Thanks.

0 Kudos
Reply
4,294 Views
soledad
NXP Employee
NXP Employee

Thank you for your feedback, we are checking this issue internally. 

We will keep you informed. 

Regards 

Soledad 

4,294 Views
dmarks_ls
Senior Contributor II

soledad‌, 

Has this issue been corrected?

David R.

0 Kudos
Reply
4,294 Views
dmarks_ls
Senior Contributor II

OK, this is definitely a bug, and I'm surprised that NXP QC allowed this to go out the door.

I encountered this exact same issue when I was upgrading my RT1050 project from MCUX 10.3.1 to MCUX v11.0.0.  MCUX 11 uses the new version of the GCC 8 compiler, and apparently the C++ compiler is more strict about certain things that are generally OK in C code.  Specifically, it is no longer a fan of dereferencing a null pointer in order to manually determine the offset of a struct member.  Here are the offending macros in fsl_clock.h in your SDK:

/* clock mux register definition */
#define CLK_MUX_DEFINE(reg, mux) (((((uint32_t)(&((SYSCON_Type *)0U)->reg)) & 0xFFU) << 8U) | ((mux)&0xFFU))
[...]
/* clock divider register definition */
#define CLK_DIV_DEFINE(reg) (((uint32_t)(&((SYSCON_Type *)0U)->reg)) & 0xFFFU)

Each of those macros pretends that there is a SYSCON_Type struct located at address 0, then references the "reg" (macro parameter) field of that struct, takes the address of that field, and then converts the address to a uint32_t.  Apparently this played nice in GCC 7 with C++ code, but GCC 8 flags this as an error (and correctly so):

../drivers/fsl_clock.h:173:64: note: in definition of macro 'CLK_DIV_DEFINE'
../drivers/fsl_clock.h:173:78: error: dereferencing a null pointer in '*0'

And since the value is borked, it then flags each and every enumeration value below, because now that value isn't a proper constant.

When I encountered this issue with my RT1050 project and MCUX 11, I was still using SDK 2.5.1.  So I upgraded my SDK, and magically the issue went away... because NXP redefined those macros.  Here's the "before":

#define CCM_TUPLE(reg, shift, mask, busyShift)                               \
    (int)((((uint32_t)(&((CCM_Type *)0U)->reg)) & 0xFFU) | ((shift) << 8U) | \
          ((((mask) >> (shift)) & 0x1FFFU) << 13U) | ((busyShift) << 26U))
[...]
#define CCM_ANALOG_TUPLE(reg, shift) ((((uint32_t)(&((CCM_ANALOG_Type *)0U)->reg) & 0xFFFU) << 16U) | (shift))

And here's the "after":

#define CCM_TUPLE(reg, shift, mask, busyShift) \
    (int)((reg & 0xFFU) | ((shift) << 8U) | \
    ((((mask) >> (shift)) & 0x1FFFU) << 13U) | ((busyShift) << 26U))
[...]
#define CCM_ANALOG_TUPLE(reg, shift) (((reg & 0xFFFU) << 16U) | (shift))
‍‍‍‍

Basically, they just got rid of the "offset of" operation altogether.  Now in the LPC845 code, I'm not sure if the same trick works.  But, there's really no need to explicitly do a null pointer dereference... there's a standard C construct for this, offsetof() (located in stddef.h).  If you look in stddef.h, you'll see that it's not defined the way it is in the Wikipedia article, but rather to call the intrinsic function of the compiler:

/* Offset of member MEMBER in a struct of type TYPE. */
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)

Replace the two offending macros in fsl_clock.h with these:

#define CLK_MUX_DEFINE(reg, mux) (((offsetof(SYSCON_Type, reg) & 0xFFU) << 8U) | ((mux)&0xFFU))

#define CLK_DIV_DEFINE(reg) (offsetof(SYSCON_Type, reg) & 0xFFFU)

I did this, and a basic C++ project for the LPC845 (using your supplied SDK) builds fine.  Hope this helps.

NXP, you need to scrub all of your libraries for all of your supported parts, find every place where you explicitly dereference a null pointer to calculate the offset of a member, and use the "offsetof()" macro instead.  Otherwise, that code will generate a compiler error whenever it's used in C++ code.

4,285 Views
mosesmcknight
Contributor I

I'm having this same issue using MCUexpresso 11.2.0 and SDK 2.8.0 for LPC812.  In my case the first patch for CLK_MUX_DEFINE fixed that problem, but with the patch for CLK_DIV_DEFINE I'm now getting a whole lot of errors like this:

../drivers/fsl_clock.h:244:27: note: in expansion of macro 'CLK_DIV_DEFINE'
244 | kCLOCK_IOCONCLKDiv0 = CLK_DIV_DEFINE(IOCONCLKDIV0),
| ^~~~~~~~~~~~~~
../drivers/fsl_clock.h:158:74: error: stray '\215' in program

Any ideas what the problem there is?

0 Kudos
Reply
4,283 Views
mosesmcknight
Contributor I

Ok, forget that, it seems there was a bad character or something in there from copy and pasting from the website.  I typed it out manually and recompiled and that fixes the problem.  Thanks for this post!  NXP should really test their SDK with C++...

0 Kudos
Reply
3,974 Views
diego_charles
NXP TechSupport
NXP TechSupport

Hi @mosesmcknight 

Please take a look at SDK 2.9 for LPC812. We added the changes to having a successful build after creating a CPP project. 

Many thanks for your comments. 

Diego.

0 Kudos
Reply
3,951 Views
1234567890
Contributor IV

Now the (very, very tiny) fix works as expected, and that only 2 years later...

4,294 Views
1234567890
Contributor IV

Hi,

thanks a lot for your detailed description and the solution. Your patch solved the problem.

4,294 Views
dmarks_ls
Senior Contributor II

Glad I could help.  NXP, please acknowledge the issue, thanks.

4,294 Views
dmarks_ls
Senior Contributor II

Can you provide some of the "strange errors"?  I'm building a C++ project on RT1050 with SDK 2.6.0 just fine.

0 Kudos
Reply
4,294 Views
1234567890
Contributor IV

See the attachment. Unfortunately it overflows the buffer, so the beginning is overwritten.

I haven't checked other mcu with SDK 2.6.0.