Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VS2015 cannot fathom static inline functions

I have the following function defined in a header file of a visual studio makefile project that eventually builds in c using msys-rtems:

static inline UInt32 timer_now() {
    ...

Where the type UInt32 is a typedef from a included header file:

typedef unsigned long UInt32;

I get the following problems with my intellisense because of that function:

  1. Intellisense suggests inline is not a type name. >Error: Variable 'inline' is not a type name
  2. Intellisense thinks that the definition of UInt32 is this function instead of the typedef unsigned long.
  3. If i remove the inline keyword everything works fine (except that i dont want to because this is a function we want inlined).
  4. I don't think it is fully to do with my typedef UInt32 because if i swap this out with unsigned long i still get the same problem.
  5. There are a bunch of other functions below this one using static inline double which dont have any error unless they are moved to be the first function. Then they experience the same error.

I have tried restarting VS2015 and deleting the SQL database file. I have played with various intellisense options to no avail. Is this an intellisense bug?

As an additional note, a quick look over the remainder of the project makes it look like the first inline function in any h file has this problem.

Visual studio bug opened here.

As a more minimal example I reduced the header file to just:

#ifndef SERVOSCHED_H 
#define SERVOSCHED_H

typedef unsigned long UInt32;
static inline UInt32 timer_now() {}

#endif

And i still get this:

enter image description here

Why I don't want to just turn off intellisense.

This isn't just affecting my intellisense, otherwise i wouldnt care. The real problem is that it thinks UInt32 is declared in this line:

static inline UInt32 timer_now() {

ie. When i go to definition on any UInt32 use it takes me to this line. But its worse, because of this ANYTHING that is declared as type UInt32 cannot be found as defined. As in if i have this anywhere in our massive code base:

UInt32 ii;
...
for (ii = 0; ii < 10; ++ii) {

Then -

  1. VS thinks ii is undefined.
  2. You cannot follow ii to its definition - which is crazy annoying.

We use UInt32 and Int32 literally everywhere and anything declared with these types cannot be easily found which is a huge problem.

Why i dont want to just change the inline

I know that the static inline keywords might not do anything on this particular code. Its not that i don't want to change it. It is that i cant change it. This code is compiled as c in GCC 3.4.5. The compiler is a cross compiler written for RTEMS under the Power PC 5200 board BSP. How do you think it will change the assembly code when you just remove the inline? Don't know? Neither do I. Given that this is running a real time system that can affect safety functionality. I don't just not want to change it. I cant change it until such time as we decide to upgrade the compiler as well.

Current Workaround

In order to fix this for now i have defined the following typedef:

typedef UInt32 inlineUInt32;

and have used this instead of UInt32 in the static inline function definitions. This fixes the described problem with UInt32, but i have made a change in running code (That is built with a makefile) to please Visual Studio which is stupid.

like image 497
Fantastic Mr Fox Avatar asked Sep 29 '15 18:09

Fantastic Mr Fox


1 Answers

This is a bug in the Visual C++ IntelliSense service when processing C source files (or headers included by C source files). This bug was reported several months ago on Microsoft Connect: IntelliSense does not accept "inline" C99 functions. The bug has been fixed and the fix will appear in the next update to Visual Studio 2015.

A workaround (while you await the next update to Visual Studio 2015) would be to define a macro named inline that expands to nothing, and to guard that macro so that it is only defined when the Visual C++ IntelliSense service is parsing the file.

#if defined _MSC_VER && defined __EDG__ && !defined __cplusplus
    #define inline
#endif

Ideally this macro definition would be placed in one common header that is included by everything in your project. If no such header exists, then you can place it into its own header then force-include it at the top of every file using the /FI compiler option. (This is generally inadvisable, but since you'd only be using this as a temporary workaround for this IntelliSense issue, it's probably okay.)

like image 82
James McNellis Avatar answered Oct 10 '22 23:10

James McNellis