Using Visual Studio Code for ARM Development – Defines

In the last post on Include Paths, I started with just a single error, and ended up with quite a large number of errors – it feels like going backwards! Keep in mind that the code actually builds and runs, so these are not actually problems with the code.

These errors are caused since the code I’m using, including the STM32 libraries standard ARM libraries, depend on macros that are not defined within the code itself. In this post, I will describe how to determine and pass the defines to Visual Studio Code so it will properly parse your code.

First, it is common to pass defines to the compiler using flags at compile time. In my case, I am using CMSIS and the new STM32 Low-Level library and that is included with the STM32Cube software, and I am targeting the 1bitsy development board, which uses an STM32F415 chip. In order for the library to use the right options, I need to pass these to the compiler, without them, many references to the library are not properly defined in the scope of my code.


Setting these for VSCode is simple: just add them to the “defines” section of c_cpp_properties.json, without the -D flag prefix:

    "defines": [

Aha – This fixes all of the errors related to things defined in the libraries! But I still have one strange error remaining:

Isn’t uint32_t defined in stdint.h? I’ve included that, I don’t have any include errors… Grrr!

To be honest, this was quite maddening to figure out. The GNU ARM version of stdint.h  actually drills down and leads to stdint-gcc.h, which is dependent upon a macro, but the macro isn’t defined! It’s also dependent on other macros to get there… This leaves uint32_t undefined, and the VSCode parser doesn’t know what to do with it. The same is true of all of the types defined in this file.

So why does this even compile? It turns out, that the GNU ARM compiler has many defines hard-coded into it, including __UINT32_TYPE__. The compiler will process the typedef properly, and then understand my code.

So, we need to figure out what these are, and set them for VSCode as well.

Since there are a very large number of defines (344!), I was able to dump them into a file by running

echo | arm-none-eabi-gcc -dM -E - > gcc-defines.txt

(on Windows).

#define __ATOMIC_SEQ_CST 5
#define __DA_FBIT__ 31
#define __UINT32_TYPE__ long unsigned int
#define __UINTPTR_TYPE__ unsigned int
#define __USA_IBIT__ 16

I’m not sure what all of these do, or when I might need them in the future, so I added all of them. (I used Excel to do some bulk editing tricks and sort them, but you can accomplish this however you are comfortable. I don’t want to reproduce the list as it may change with different builds of gcc; you should ensure it matches the compiler you are using!)

Again, follow the format of the -D compiler flag, just without the “-D” prefix. A few rules:

    • Put an equals sign between the macro name and the value, like
      __UINT32_TYPE__=long unsigned int
    • If the value contains quotes, escape the quotes  with \”, like
      __VERSION__="6.3.1 20170620 (release) [ARM/embedded-6-branch revision 249437]"
    • If there is no value provided, just use the macro name, like

My defines section is now very long:

 "defines": [


But now my error is gone, and hovering over the type shows it is defined!

If the include paths and defines are properly set up in Visual Studio Code, the C/C++ plugin should be able to properly parse your code, identify syntax errors, and will provide Intellisense code completion to improve the speed and accuracy of your writing!

In the next post, I will describe how build your code using Makefiles from within Visual Studio Code.

Leave a Reply

4 Comment threads
1 Thread replies
Most reacted comment
Hottest comment thread
5 Comment authors
JackschperplataBen BooherBrianDave Marples Recent comment authors
newest oldest most voted
Notify of
Dave Marples

A bit of sed magic like this will create the list you need from a Linux command line;

echo | arm-none-eabi-gcc -dM -E – | sed “s/#define //;s/ /=/;s/.*/\”&\”,/”


In reference to your uint32_t problem, you can simply define “__CC_ARM” and core_cm(3 or 4).h will take it from there.

Ben Booher
Ben Booher

In the previous post, you have:
“intelliSenseMode”: “clang-x64”

I’ve found if you update that line to:
“intelliSenseMode”: “gcc-x64”

then the type inclusion works without mucking with extra defines.


I wish I would have found this site and posts earlier! Here is my implementation how to use VS Code as an IDE for embedded projects together with CubeMX, OpenOCD and python scripts:


@schperplata … The DamogranLabs solution you posted is downright amazing. It took me a while to figure out (mostly because I’m new to VSCode), but I got it working on my Nucleo F446 and it is sooooo much better than working in Eclipse. A big THANK YOU!