VS2015 cannot fathom static inline functions - c++

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:
Intellisense suggests inline is not a type name. >Error: Variable 'inline' is not a type name
Intellisense thinks that the definition of UInt32 is this function instead of the typedef unsigned long.
If i remove the inline keyword everything works fine (except that i dont want to because this is a function we want inlined).
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.
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:
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 -
VS thinks ii is undefined.
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.

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

From the example given, it is clear that 'inline' is not needed there, and can be safely removed. Expalanation:
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.
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'
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.

Related

Duplicate symbol issue with C headers

This is my first time tackling a CUDA project that's slightly more complex than the simple write-single-source-file-and-compile routine. As expected, I'm facing some issues with C headers, namely duplicated symbols.
According to the linker, conflicts arise over the inclusion of the following header file in multiple .cu files:
env_vars.h
#ifndef ENV_VARS_H_
#define ENV_VARS_H_
/*** GLOBAL VARIABLES ***/
unsigned int h_n_osc;
__device__ unsigned int d_n_osc;
/*** CONSTANTS ***/
const double OMEGA_0 = 6.447421494058077e+09;
/* other constants defined in the middle */
#endif
multigpu.cu
#include "env_vars.h"
/* assigns h_n_osc */
adm_matrix.cu
#include "env_vars.h"
/* uses h_n_osc */
Building the project in Nsight Eclipse Edition results in the linker complaining about the h_n_osc variable being defined twice:
duplicate symbol _h_n_osc in:
./adm_matrix.o
./multigpu.o
ld: 1 duplicate symbol for architecture x86_64
Searching through the Internet, I've realized that moving the declaration of the h_n_osc variable to multigpu.cu and re-declaring it as an extern variable in adm_matrix.cu (and wherever I might need it later) solves the problem, which in fact it does.
Problem solved, but I'd like to take a deeper look into this:
Why doesn't the linker complain about the d_n_osc variable as well? And why are the constants (such as OMEGA_0) equally not a problem?
Does this mean that it is not possible to place global variables in header files?
What puzzles me most is that a number of sources over the Internet state that duplicated symbol errors should happen only when the header file contains a definition of the variable, while its simple declaration shouldn't constitute a problem. The reason I have a hard time believing this is that I'm facing the issue even though my header only contains a declaration! Am I missing something?
Thanks in advance for your patience, folks!
Header files should normally contain only declarative code. h_n_osc should be declared here, not defined.
extern unsigned int h_n_osc;
In at least one of your modules, or a new one of its own you will need a definition; for example:
env_vars.cu
#include "env_vars.h"
unsigned int h_n_osc;
Then link that. Alternatively you could of course place the definition in one of the existing modules multigpu.cu or adm_matrix.cu.
I am not sure of the semantics of the The CUDA __device__ extension, while it may link, it is not necessarily correct; you may end up with each module referencing a separate copy of the device variable; it may be necessary to qualify that with extern as well. This question appears to deal with that issue.

Importing inline functions in MinGW

I'm using a shared library that defines inline functions in its header.
Here is a reduced test case, as seen by the compilation unit linking to the library (for the version seen by the library, just replace dllimport by dllexport).
class __declspec(dllimport) MyClass {
public:
int myFunc2();
int myFunc1();
};
inline int MyClass::myFunc2(void) {
return myFunc1();
}
inline int MyClass::myFunc1(void) {
return 0;
}
Compiling this gives the warning:
warning: 'int MyClass::myFunc1()' redeclared without dllimport
attribute after being referenced with dll linkage [enabled by default]
Please note that the order in which the functions are defined is important, as putting the definition of myFunc1 before the definition of myFunc2 results in no warnings.
Note also that this code compiles without warnings under Visual C++. These warnings are specific at least to MinGW, maybe to GCC in general. Edit: it came to my mind that I may have to verify if the warning is not inhibited by one of the flags set by the project.
My questions are then:
Why this behavior ?
Declaring myFunc1 as inline inside the class declaration fixes the problem. Why is that ? It's also against the recommended way of doing things.
Is there another (better ?) way to fix this problem ?
The problem comes about because of some magic in the way that dllimport works which normally means you only need it on the first declaration.
Basically, when you declare a function as dllimport and then later redeclare the function with an identical declaration except for the dllimport, the second declaration implicitly gets the dllimport. If the redeclaration is NOT identical, it doesn't get the implicit dllimport.
So what happens here is you first declare the function as dllimport/non-inline, and then declare it as non-dllimport/inline. Adding an inline to the first declaration fixes the problem, as the second then becomes implicitly dllimport. Alternately, adding a __declspec(dllimport) to the second declaration should fix the problem.
Note that reordering the definitions gets rid of the warning, since the warning is about using it before redeclaring it. With a reorder, you're no longer using it before the redeclaration, so you get no warning, though it will be using the non-dllimport version (ie, it will never use the version of the function from the dll).
Note also, using inline dllimport is dangerous. Any program built against the dll might use the inline function in some places and the non-inline function (from the dll) in others. Even if the two functions are identical NOW, a future version of the dll might change and have a different implementation. At which point the old program might start misbehaving if run with the new version of the dll.
Further information to Chris Dodd's answer:
I tested with MSVC 2017 and MinGW-w64 7.2.0; in both cases, with optimization enabled, the call of myFunc1() from myFunc2 resolved to the inline version, despite the warning. Even if the body of myFunc1 were moved to below main().
So my tentative conclusion is that it is safe to ignore this warning.
In the interest of a clean compile, the only method that seems to work in MinGW-w64 is to mark the function declaration within the class definition as inline. The compiler does not allow applying __declspec(dllimport) to the out-of-class function definition.
I have been unable to determine if there is a warning flag for g++ which will specifically disable this warning.

Best code for compiling static const int = X in VS2008 and GCC

I have run into a problem while writing C++ code that needs to compile in Visual Studio 2008 and in GCC 4.6 (and needs to also compile back to GCC 3.4): static const int class members.
Other questions have covered the rules required of static const int class members. In particular, the standard and GCC require that the variable have a definition in one and only one object file.
However, Visual Studio creates a LNK2005 error when compiling code (in Debug mode) that does include a definition in a .cpp file.
Some methods I am trying to decide between are:
Initialize it with a value in the .cpp file, not the header.
Use the preprocessor to remove the definition for MSVC.
Replace it with an enum.
Replace it with a macro.
The last two options are not appealing and I probably won't use either one. The first option is easy -- but I like having the value in the header.
What I am looking for in the answers is a good looking, best practice method to structure the code to make both GCC and MSVC happy at the same time. I am hoping for something wonderfully beautiful that I haven't thought of yet.
I generally prefer the enum way, because that guarantees that it will always be used as immediate value and not get any storage. It is recognized as constant expression by the compiler.
class Whatever {
enum { // ANONYMOUS!!!
value = 42;
};
...
}
If you can't go that way, #ifdef away the definition in the .cpp for MSVC, because if you ifdef away the value in declaration, it will always get storage; the compiler does not know the value, so it can't inline it (well, the "link time code generation" should be able to fix that up if enabled) and can't use it where constant is needed like value template arguments or array sizes.
If you don't dislike the idea of using non-standard hacks, for VC++ there's always __declspec(selectany). My understanding is that it will ensure that at link time, any conflicts are resolved by dropping all but one definition. You can potentially put this in an #ifdef _MSC_VER block.
The Visual C++ 2010 accepts this:
// test.hpp:
struct test {
static const int value;
};
// test.cpp:
#include "test.hpp"
const int test::value = 10;
This is still a problem with VS2013. I've worked around it by putting my standard-compliant definition, in the cpp file, inside a #if preventing VS.
a.h:
class A
{
public:
static unsigned const a = 10;
};
a.cpp:
#ifndef _MSC_VER
unsigned const A::a;
#endif
I also commented it well, so the next guy in the file knows which compiler to blame.

Using C++ with Objective-C, How can I fix "Conflicting declaration 'typedef int BOOL'"?

I have a lot of code in C++, originally built on a PC. I'm trying to make it work with Objective-C on a Mac. To that end, I created an Objective-C framework to house the C++ code and added a thin wrapper. But I'm running into a typedef problem in my C++ code.
When I was working with C++ on a PC I used the BOOL variable defined in WinDef.h. So when I moved everything over the Mac I added in typedef int BOOL; to make sure the BOOL variable would still compile as expected.
But when I try to compile I get an error: "Conflicting declaration 'typedef int BOOL'". I assume this is because BOOL is a keyword in Objective-C, and so is already defined. I also can't just use the Objective-C BOOL since it is an unsigned char and not an int.
While I was looking for possible solutions I found one that mentions undefining BOOL, but I couldn't find how to do that (nor do I know if it actually works). Another suggests renaming BOOL in the C++ files to something that isn't a keyword. This suggestion isn't an option for me because other projects rely on the C++ code. Ideally, any changes I make should stay in one file or at least should not negatively impact the code on a Windows machine.
How can I undefine the Objective-C definition of BOOL for my C++ files and use the C++ definition I added? Is there a better way to deal with this problem?
In case it helps I'm using: Xcode 3.2.5, 64-bit and Mac OS X 10.6.6
Thanks for any guidance!
I'm a little confused by some of the discussion, but instead of typedef int BOOL; how about just:
#ifndef BOOL
#define BOOL int
#endif
If you're using typedef then #undef won't work since they are two different things. #define/#undef operate on preprocessor symbols that perform replacements, whereas a typedef is part of the language that creates an alias of another type.
A preprocessor symbol can be undefined at any point because it is simply an instruction to the preprocessor that tells it to no longer use that definition when performing replacements. However, a typedef can't be undefined, as it is something that gets created within a particular scope, rather than the linear processing that occurs using the preprocessor. (In the same way, you wouldn't expect to be able to declare a global variable int x; and then at some point in your code be able to say 'stop recognizing x as a variable.')
The reason I suggest the #define in my answer is that it's possible that the ObjectiveC #define is being hit only while compiling some of your code. That could be an explanation as to why you may get errors in your C++ when you removed the typedef, but still get a conflict if it is in. But, so, if the assumptions are correct, once you check for the definition prior to trying to define it, you should be able to avoid the conflicting definitions when they occur.
As a final note: in this particular situation, you could also just put your typedef inside the check instead of a #define. However, I gravitated toward doing it the way I did both because it's a very common idiom, and because that block will also prevent you from defining it twice in your C++ code if it ends up included twice. Probably neither very compelling reasons if you very much prefer the typedef and know it's not an issue in the code. :)
AFAIK, BOOL is a #define in Objective-C too. You will have problems with your conflicting BOOL define, even if you manage to
#undef BOOL
because your type and its type do not necessarily match in size and "signedness". Must your BOOL really be an int, instead of whatever it is that Obj-C defines it as? In other words, can't you omit your #define and simply use the Obj-C one?
If you could go back in time, I would say "Don't use typedef int BOOL in your own code".
Now that you've actually done it, though, you are in a bit of a pickle. Generally, you should avoid using external data types for your own code except to interface with external code. Standard types are fine, assuming that you can guarantee compiling with a standard compliant compiler on every platform you target.
The most forward looking solution is to stop using BOOL as a type in your platform agnostic code. In the meantime, you can use all sorts of preprocessor hackery to make your use of BOOL compile, but you might hit some strange link errors if you don't use BOOL in the same way (via #includes) everywhere.
I use cmake to load the freeimage library and i'm using kubuntu 14.x
I had this problem with
"error: conflicting declaration ‘typedef CARD8 BOOL’"
and I thought it would be good to share my solution with people that have this problem!
install FreeImage on Linux:
sudo apt-get install libfreeimage-dev
In my CMakeLists.txt file I have:
set(FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY /usr/libs)
find_path(FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY, FreeImage.h)
find_library(FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY, freeimage)
include_directories(${FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY})
target_link_libraries(freeimage)
And in my main.cpp I have:
#include <FreeImage.h>
#ifndef CARD8
#define BYTE CARD8
#define BOOL CARD8
#endif
And some extra code to capture OpenGl frame on disk:
void generateImage(){
int w, h; // get the width and height of the OpenGL window!
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
GLubyte * pixels = new GLubyte[3*w*h];
glReadPixels(0,0,w,h,GL_RGB,GL_UNSIGNED_BYTE, pixels);
FIBITMAP * image = FreeImage_ConvertFromRawBits(pixels,w,h,3 * w, 24, 0x0000FF, 0xFF0000, 0x00FF00, false);
FreeImage_Save(FIF_BMP,image, "../img/text.bmp",0);
//Free resource
FreeImage_Unload(image);
delete[] pixels;
}
I hope this helps the ones who have problem with this!
Regards
Kahin

In C/C++, is there a directive similar to #ifndef for typedefs?

If I want to define a value only if it is not defined, I do something like this :
#ifndef THING
#define THING OTHER_THING
#endif
What if THING is a typedef'd identifier, and not defined? I would like to do something like this:
#ifntypedef thing_type
typedef uint32_t thing_type
#endif
The issue arose because I wanted to check to see if an external library has already defined the boolean type, but I'd be open to hearing a more general solution.
There is no such thing in the language, nor is it needed. Within a single project you should not have the same typedef alias referring to different types ever, as that is a violation of the ODR, and if you are going to create the same alias for the same type then just do it. The language allows you to perform the same typedef as many times as you wish and will usually catch that particular ODR (within the same translation unit):
typedef int myint;
typedef int myint; // OK: myint is still an alias to int
//typedef double myint; // Error: myint already defined as alias to int
If what you are intending to do is implementing a piece of functionality for different types by using a typedef to determine which to use, then you should be looking at templates rather than typedefs.
C++ does not provide any mechanism for code to test presence of typedef, the best you can have is something like this:
#ifndef THING_TYPE_DEFINED
#define THING_TYPE_DEFINED
typedef uint32_t thing_type
#endif
EDIT:
As #David, is correct in his comment, this answers the how? part but importantly misses the why? It can be done in the way above, If you want to do it et all, but important it you probably don't need to do it anyways, #David's answer & comment explains the details, and I think that answers the question correctly.
No there is no such facility in C++ at preprocessing stage. At the max can do is
#ifndef thing_type
#define thing_type uint32_t
#endif
Though this is not a good coding practice and I don't suggest it.
Preprocessor directives (like #define) are crude text replacement tools, which know nothing about the programming language, so they can't act on any language-level definitions.
There are two approaches to making sure a type is only defined once:
Structure the code so that each definition has its place, and there's no need for multiple definitions
#define a preprocessor macro alongside the type, and use #ifndef to check for the macro definition before defining the type.
The first option will generally lead to more maintainable code. The second could cause subtle bugs, if you accidentally end up with different definitions of the type within one program.
As other have already said, there are no such thing, but if you try to create an alias to different type, you'll get a compilation error :
typedef int myInt;
typedef int myInt; // ok, same alias
typedef float myInt; // error
However, there is a thing called ctag for finding where a typedef is defined.
The problem is actually real PITA, because some APIs or SDKs redefine commonly used things. I had issue that header files for a map processing software (GIS) were redefining TRUE and FALSE (generally used by windows SDK)keywords to integer literals instead of true and false keywords ( obviously, that can break SOMETHING). And yes, famous joke "#define true false" is relevant.
define would never feel a typedef or constant declared in C\C++ code because preprocessor doesn't analyze code, it only scans for # statements. And it modifies code prior to giving it to syntax analyzer. SO, in general, it's not possible.
https://msdn.microsoft.com/en-us/library/5xkf423c.aspx?f=255&MSPPError=-2147217396
That one isn't portable so far, though there were known request to implement it in GCC. I think, it also counts as "extension" in MSVC. It's a compiler statement, not a preprocessor statement, so it will not "feel" defined macros, it would detect only typedefs outside of function body. "full type" there means that it will react on full definition, ignoring statements like "class SomeClass;". Use it at own risk.
Edit: apparently it also supported on MacOS now and by Intel comiler with -fms-dialect flag (AIX\Linux?)
This might not directly answer the question, but serve as a possible solution to your problem.
Why not try something like this?
#define DEFAULT_TYPE int // just for argument's sake
#ifndef MY_COOL_TYPE
#define MY_COOL_TYPE DEFAULT_TYPE
#endif
typedef MY_COOL_TYPE My_Cool_Datatype_t;
Then if you want to customize the type, you can either define MY_COOL_TYPE somewhere above this (like in a "configure" header that is included at the top of this header) or pass it as a command line argument when compiling (as far as I know you can do this with GCC and LLVM, maybe others, too).
No there is nothing like what you wanted. I have had your same problem with libraries that include their owntypedefs for things like bool. It gets to be a problem when they just don't care about what you use for bool or if any other libs might be doing the same thing!!
So here's what I do. I edit the header file for the libs that do such things and find the typedef bool and add some code like this:
#ifdef USE_LIBNAME_BOOL
typedef unsigned char bool; // This is the lib's bool implementation
#else
#include <stdbool.h>
#endif
Notice that I included if I didn't want to use the libs' own bool typdef. This means that you need C99 support or later.
As mentioned before this is not included in the C++ standard, but you might be able to use autotools to get the same functionality.
You could use the ac_cxx_bool macro to make sure bool is defined (or different routines for different datatypes).
The solution I ended up using was including stdbool.h. I know this doesn't solve the question of how to check if a typedef is already defined, but it does let me ensure that the boolean type is defined.
This is a good question. C and Unix have a history together, and there are a lot of Unix C typedefs not available on a non-POSIX platform such as Windows (shhh Cygwin people). You'll need to decide how to answer this question whenever you're trying to write C that's portable between these systems (shhhhh Cygwin people).
If cross-platform portability is what you need this for, then knowing the platform-specific preprocessor macro for the compilation target is sometimes helpful. E.g. windows has the _WIN32 preprocessor macro defined - it's 1 whenever the compilation target is 32-bit ARM, 64-bit ARM, x86, or x64. But it's presence also informs us that we're on a Windows machine. This means that e.g. ssize_t won't be available (ssize_t, not size_t). So you might want to do something like:
#ifdef _WIN32
typedef long ssize_t;
#endif
By the way, people in this thread have commented about a similar pattern that is formally called a guard. You see it in header files (i.e. interfaces or ".h" files) a lot to prevent multiple inclusion. You'll hear about header guards.
/// #file poop.h
#ifndef POOP_H
#define POOP_H
void* poop(Poop* arg);
#endif
Now I can include the header file in the implementation file poop.c and some other file like main.c, and I know they will always compile successfully and without multiple inclusion, whether they are compiled together or individually, thanks to the header guards.
Salty seadogs write their header guards programmatically or with C++11 function-like macros. If you like books I recommend Jens Gustedt's "Modern C".
It is not transparent but you can try to compile it one time without typedef (just using the alias), and see if it compiles or not.
There is not such things.
It is possible to desactivate this duplicate_typedef compilator error.
"typedef name has already been declared (with same type)"
On a another hand, for some standardized typedef definition there is often a preprocessor macro defined like __bool_true_false_are_defined for bool that can be used.