5

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.

Fantastic Mr Fox
  • 32,495
  • 27
  • 95
  • 175
  • It looks like it. It compiles right? – NathanOliver Sep 29 '15 at 18:33
  • @NathanOliver This is a makefile project and it compiles just fine. That is with GCC though. – Fantastic Mr Fox Sep 29 '15 at 18:33
  • `inline` is only a hint; even if you don't mark it `inline`, the compiler will still treat it as a candidate for being inlined. – Collin Dauphinee Sep 29 '15 at 18:35
  • @CollinDauphinee, correct, but is there any reason i should not mark inline? Surely not just to satisfy intellisense .... – Fantastic Mr Fox Sep 29 '15 at 18:37
  • It compiles on VS2008. Do you have a missing semicolon on the line before the word static? – cup Sep 29 '15 at 18:38
  • @cup It compiles fine in VS2015. Its only intellisense that has a problem. – Fantastic Mr Fox Sep 29 '15 at 18:39
  • Not a problem with intellisense on VS2008. – cup Sep 29 '15 at 18:41
  • @cup yep, so i suspect maybe a VS2015 intellisense bug ... – Fantastic Mr Fox Sep 29 '15 at 18:42
  • I recommend not listening to Intellisense. It often disagrees with the errors from the compiler (or absence of errors). For more accurate help, get a *static analysis* tool. – Thomas Matthews Sep 29 '15 at 19:04
  • @ThomasMatthews I am fine not listening to its build advice. But this is causing 2 problems. 1. Go to definition doesn't work for the some of the types that we have defined. 2. Squiggly lines everywhere (I know we can turn them off but im trying to see if i can get it working first). – Fantastic Mr Fox Sep 29 '15 at 19:05
  • Are you definitely compiling C++ rather than C? (`inline` behaves differently in each language) – M.M Sep 29 '15 at 20:48
  • @M.M It is a makefile project. Although the code is compiled (in `c`) using GCC, this is done by a batch file called by visual studio. As for the language that intellisense uses to parse it, i have no idea how to determine if it thinks it is C or C++. – Fantastic Mr Fox Sep 29 '15 at 20:52
  • If it is C perhaps you should use the C tag rather than the C++ tag for this question. To confirm what intellisense is doing you could add some code that is clearly illegal in C++, e.g. `int new;` – M.M Sep 29 '15 at 21:05
  • @M.M I suspect it is at least C++11 because `new` ,`class` and `auto` are all recognized as keywords (and don't cause any intellisense problems). – Fantastic Mr Fox Sep 29 '15 at 21:07
  • @Ben if the code contains those keywords (not being used as identifiers) then it will not be able to be compiled in C (using gcc or any other compiler) – M.M Sep 29 '15 at 21:09
  • @M.M So i added those keywords to check intellisense which is clearly checking for c++ code. The code is being compiled as `c` using an external compiler (`mingw`). What i am concerned with is intellisense telling me that an inline keyword is a type name. – Fantastic Mr Fox Sep 29 '15 at 21:11
  • @Ben Sorry, do you mean that the code contains new, class and auto; or you just added them now to test intellisense? If the latter then maybe look for a way to let intellisense know that this is C rather than C++ (i'm not sure whether this is possible) – M.M Sep 29 '15 at 21:13
  • Also it would be good to have an MCVE (e.g. check that the problem still happens when your file is just a single line `static inline void f() {}` – M.M Sep 29 '15 at 21:13
  • @M.M Yes, as per your advice i added them to check intellisense. The code is absolutely running C. I dont think there is a way to convert intellisense to using C, at least i cant find it. As for the MCVE, i can not reproduce it using a small function created from scratch. I am working on stripping away stuff as i go, but its difficult with the size of the code base. – Fantastic Mr Fox Sep 29 '15 at 21:14
  • @M.M Also yes, when the funtion definition is the only thing in the file it will still have the bug. (also i had the typedef include). – Fantastic Mr Fox Sep 29 '15 at 21:28
  • I disable intellisense error reporting because it is often wrong. – Neil Kirk Oct 01 '15 at 20:45
  • @NeilKirk As i have explained, its not just affecting my intellisense. Bassiclly it thinks the type `UInt32` is **declared** in this `inline` function. Which means that anything declared as UInt32 (which is a lot of things) cannot be followed to definition. I might add this to the question ... – Fantastic Mr Fox Oct 01 '15 at 21:13
  • 1
    Have you tried `inline static`? – 1201ProgramAlarm Oct 02 '15 at 05:04
  • You ask "Is this an intellisense bug?". No, it isn't a general VS2015 intellisense bug. My VS2015 (Community Edition) intellisense handles your code example perfectly well. Perhaps something in your environment is causing it? – cdmh Oct 02 '15 at 14:33
  • Can you reproduce the problem in a *new project* ? – cdmh Oct 02 '15 at 14:34
  • @1201ProgramAlarm `Inline static` does avoid the major problem described and fixed with my workaround. But inline is still not recognized as a keyword. So good catch. – Fantastic Mr Fox Oct 02 '15 at 15:07
  • @cdmh I wasn't able to either, thats what makes this so strange. Looking through my project properties i cant see anything out of the ordinary. It is a makefile project so the only thing affecting this should be the Intellisense options under `NMake`. The only thing i have in there are a bunch of include directories (all which exist) and some pre-processor definitions. Can you think of anything else that could cause this? – Fantastic Mr Fox Oct 02 '15 at 15:10
  • @Ben if you don't already, try setting "Always Use Fallback Location" to True, and set a Fallback Location (e.g. `C:\Temp`) in Options|Text Editor|Advanced. There's also a bunch of options for Intellisense in there, but I've never changed any of those from their default. – cdmh Oct 02 '15 at 15:15
  • @cdmh It was already set ... :( – Fantastic Mr Fox Oct 02 '15 at 15:17
  • What file extension is the makefile generating? – Casey Oct 02 '15 at 19:27
  • @Casey I don't see how that is relevant, but it creates ab bunch of folders with object files. It will eventually compile and link together using the `rtems-msys` cross compiler and create an image file with the RTEMS operating system and our run-time code. – Fantastic Mr Fox Oct 02 '15 at 19:29
  • @Casey - For your edit, i believe this is one of the few times when the `c++` and `c` tags are necessary, since i am building in `c` and VS is interpreting everything as `c++` – Fantastic Mr Fox Oct 02 '15 at 19:33
  • The reason I was asking is the default behavior for Visual Studio is "interpret the language based on the file extension" and I was thinking that was the root of the problem. Visual Studio sees a `.cpp` and regardless of the content compiles it as a C++ file, but obviously this is not the case. :P – Casey Oct 02 '15 at 20:01
  • C89 (that's the C standard supported by Microsoft) has no `inline` keyword. Why do you expect intellisense to recognize it? – n. m. could be an AI Oct 05 '15 at 23:38
  • Why does intellisense recognize `auto` and `class` in `c` files? but not inline? Also i didnt know that MS only supported C89, seems kinda bad ... – Fantastic Mr Fox Oct 05 '15 at 23:50

2 Answers2

10

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.)

James McNellis
  • 348,265
  • 75
  • 913
  • 977
-4

From the example given, it is clear that 'inline' is not needed there, and can be safely removed. Expalanation:

  1. if timer_now() is defined inside the class, inline is not needed there, since definitions inside the class are always inline. Remove to reduce the clutter.
  2. timer_now() CAN NOT be a definition of free-standing function in the header file, since in this case it would not be marked 'static'
  3. If timer_now() is a definiton withing .cpp file, inline is not needed, since if the function can be inlined by the compiler, it will be inlined, and there is no requirement to mark it inline.
SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • 1. Its not. 2. It CAN be a standalone static inline: http://ideone.com/R0KeZZ 3. Its not. My objective here is not to change the code in any way. It is to figure out why intellisense thinks that `inline` is a type name. – Fantastic Mr Fox Sep 29 '15 at 19:49
  • @Ben, while it can, it should not. Nothing is more deceiving than freestanding static functions in headers, and whenever I see one, "I reach for my gun". Btw, your example is not an illustration of the topic, since you are doing case 3. In this case, inline is deceiving and rubbish. Of course, you might not want to clean up your code from rubbish, but it is your code and you are having problems with it, not me. – SergeyA Sep 29 '15 at 19:52
  • I would be happy for suggestions about how to fix the issue with intellisense. As for the code, it is not mine i am simply responsible for porting it from VS2008 to VS2015. I am not looking to change any of the running code because it builds on an old compiler and minor modifications can cause big problems on the cross compiled device. Regardless of whether it is good code or not, would you expect intellisense to throw the error described on a c++ keyword? I think not. – Fantastic Mr Fox Sep 29 '15 at 19:55
  • Also, I'm doing case 2. I know the ideone example is in a cpp file but the equivalent with a header file works also. – Fantastic Mr Fox Sep 29 '15 at 19:59
  • 2. Incorrect (although probably true). 3. Incorrect (although sometimes true). – Neil Kirk Sep 29 '15 at 20:09
  • @NeilKirk, care to elaborate? What is 'incorrect' about my statements? – SergeyA Sep 29 '15 at 20:35
  • You can put static free-standing functions in a header file, although it's usually not a good idea. Functions that can be inlined are not necessarily inlined by the compiler. Although it's up to the compiler, some real ones do take into account the inline keyword when determining the probability of inlining a function, so it can make sense to make such a function inline. – Neil Kirk Sep 29 '15 at 21:56