C26495 Variable Specific - visual-c++

Is there a way to disable the VS's C26495 warning (Always initialize a member variable) for specific variables? Some member variables should not be initialized in the constructor. Examples include those in MFC's InitInstance and OnNewDocument.
#pragma warning disable C26495 and #pragma warning restore C26495 surrounding the variables in the class declaration or around the constructor didn't work. Any ideas?

Related

How to inline assembly into file scope passing Rust-defined constants?

I need the same behavior as the global_asm! macro, but passing constants defined in my Rust code. The obvious choice would be to use a (private) naked function that contains inline asm! instruction, but I don't see any way to prevent such a function from being removed by linker as unused. Can you suggest a proper way of doing that?

inconsistent dll linkage & definition of dllimport static data member not allowed

Assuming I have these two files:
Header.h
class DLL ExportClass{
public:
ExportClass();
static int test;
};
Source.cpp
#ifdef EXPORT
#define DLL __declspec(dllexport)
#else
#define DLL __declspec(dllimport)
#endif
#include "Header.h"
int ExportClass::test = 0;
ExportClass::ExportClass(){
}
And I won't define EXPORT (to import a already exported class with a static member), why do I get these warnings:
1>source.cpp(11): warning C4273: 'test' : inconsistent dll linkage
1> header.h(4) : see previous definition of 'public: static int ExportClass::test'
1>source.cpp(13): warning C4273: 'ExportClass::ExportClass' : inconsistent dll linkage
1> header.h(3) : see previous definition of '{ctor}'
And this error:
1>source.cpp(11): error C2491: 'ExportClass::test' : definition of dllimport static data member not allowed
If I define EXPORT it works. I kind of understand the warnings, but I thought, that the static variable and the ctor could be ignored by the compiler, because the whole class is declared as __declspec(dllimport) anyway. I want to use the same codebase for the __declspec(dllexport) and __declspec(dllimport) - but it seems the compiler stll tries to define these symbols that are marked as __declspec(dllexport) in their declaration. What is the common practice to solve this problem?
You are expecting the compiler to ignore a very serious mishap. It encountered the __declspec(dllimport) attribute on the class declaration, that quite unequivocally states that the class implementation is present in different module that's going to bound at runtime. But then it encountered the definition as well, completely unexpected since the attribute contract says that it is compiled in an entirely different project.
The C4273 warning is generated to remind you that it is very unclear what function is actually going to execute at runtime. There are two, one that is busy compiling, another in the DLL. Which one will actually execute is a wild guess. C4273 is a level 1 warning, the kind that fit the "this is almost surely wrong" category. It is not entirely impossible to work okay since there's some expectation that the functions have at least the same code. The odds that will not cause trouble are however not great, it could only work if the function doesn't have any side effects that change the internal DLL state. Very hard to diagnose bug when it does btw.
Then it encountered the exported variable. Same case, there are two of them. This is where the compiler programmer put his foot down, having code randomly use one or the other is no longer something that can be ignored. That just cannot ever work, the variables cannot have the same value. So C2491 is a hard error.
No idea how you got in this pickle, clearly the road you're trying to travel will make you fall off a steep cliff.
The only way I can reproduce your problem is to do the following:
Create a Win32 DLL project, call it Project1
Add the source code as you described
Compile the DLL and LIB
Change the project properties to remove EXPORT from the preprocessor definitions
Attempt to compile again (then I see your errors/warnings)
If, instead of steps 4 and 5, I do the following, I do not see an error:
Create a Win32 console application, call it Project2
Add source code as follows:
#include "Project1.h"
#pragma comment(lib, "Project1.lib")
int _tmain(int argc, _TCHAR* argv[])
{
ExportClass pClass;
return 0;
}
I suspect you see those errors because you are doing everything from the same DLL project and it is overwriting the LIB that it previously created and then attempting to import it.
If I am correct in guessing what you did, can you try using your DLL/LIB from another project and see what happens?
Although it is an old thread, it will be probably read by others. Therefore, if you want to make this code cross-compilable, I would usually define a header "export.h" like:
export.h
#pragram once
#if ! defined(DLL_API)
# if defined(_WIN32) // for windows builds
# if defined(myDLL_EXPORTS)
# define DLL_API __declspec(dllexport)
# else
# define DLL_API __declspec(dllimport)
# endif
# else // for linux builds
# define DLL_API
# endif
#endif
and include it in all the classes (.h) you want to export from your dll. You will also have to define the variable myDLL_EXPORTS as a parameter of the compiler for the dll project.
The way it works is very simple, when you are compiling your dynamic library (dll/so), because the variable myDLL_EXPORTS is defined, the compiler will replace DLL_API with __declspec(dllexport) so that your class can be consumed by the user of your dll. Conversely, when you are including the header file where you want to use your class at, because the variable myDLL_EXPORTS is not defined in the consumer project (it is defined only in the DLL project), the compiler will replace myDLL_EXPORT with __declspec(dllimport), so it knows that your class symbols are defined somewhere else (in this case, defined in your dll/so).
Finally, as __declspec(...) is a Windows-only thing, for linux we replace DLL_API with nothing.

Which is efficient to use #pragma once or #ifndef #endif?

To avoid multiple includes of a header file, one of my friend suggested the following way
#ifndef _INTERFACEMESSAGE_HPP
#define _INTERFACEMESSAGE_HPP
class CInterfaceMessage
{
/ /Declaration of class goes here
//i.e declaration of member variables and methods
private:
int m_nCount;
CString m_cStrMessage;
public:
CString foo(int);
}
#endif
where _INTERFACEMESSAGE_HPP is just an identifier
but when i declare a class using visual studio 2005 IDE I get a statement as
#pragma once
at the starting of the class definition
when i took the help of msdn to find the purpose of #pragma once
it gave me the following explanation
"Specifies that the file will be included (opened) only once by the compiler when compiling a source code file. "
Someone please tell which is the right approach?, if both are correct then what is the difference? is one approach is better than the other?
gcc has pragma once as deprecated. You should use the standard include guards. All pragma directives are by definition implementation defined. So, if you want portability, don't use them.
Pragmas are compiler-specific, so I'd use #ifndef.
Preprocessor directives are resolved during (actually, before) compilation, so they do not make a difference in runtime except maybe for compile time.
However, you will never notice a difference in compile time from these two alternatives unless you use them several thousand times I guess.
The first approach is the generic approach that works with all compilers and is also the older one around. The #pragma once approach is compiler specific.

Global Static Pointer Issue

This is a rather a problem from a convoluted situation. I have a static pointer sitting in one of my header files. Which is being included everywhere, this is why I put it as a static pointer. So that I can quickly initilize it in my main function so that other files can use it.
The problem is this, even after I initialize it and put stuff into it. Other files only find it NULL. It is like every file that includes the header with the static pointer makes a copy of it for itself and even when others initialize it, each file has their own separate copy. Negating ofcourse, the purpose of having a global variable.
How can I cope up with this?. Maybe I am understanding a static variable wrong, or maybe is it because its a pointer?
Should i be declaring it as: &variable = 5; or just as variable = 5; or &variable = (int)5?
It is like every file that includes the header with the static pointer makes a copy of it for itself and even when others initialize it, each file has their own separate copy.
That's what static means when applied to a variable at namespace scope: the variable is given internal linkage, making it "local" to a given translation unit (source file).
If you have a static variable at namespace scope in a header file and you include that header file in multiple .cpp files, there will be multiple instances of that variable: one for each of the .cpp files that include the header file.
If you want a global variable that is shared across multiple source files, you need to make it extern. Declare the variable as extern in the header file, then define the extern variable in exactly one of your .cpp files.
Yes, you are understanding the static keyword wrong. Static keyword at namespace and file scope declares a variable that is only visible inside the translation unit (basically a single .cpp file plus all of its includes) where it is declared. By declaring a static variable in header that you use in multiple .cpp files you are effectively defining multiple variables.
If you want a global pointer then declare it extern without static in the single header and define it without extern or static in a single .cpp file. E.g.:
In foo.h:
extern int * p;
and in main.cpp:
int * p = something;
Defining the global pointer static results in the C++ compiler creating a separate pointer for every translation unit, the definition is included in. I'm pretty sure it's not what you want and it's the cause of your problems.
You should declare it extern in a header and define once in one cpp file.
I can imagine the confusion came from the way, static keyword works inside a class or a struct definition. Indeed, it works differently there and it creates one variable, common for all instances of the class or struct.
Btw. In case you actually want a variable to be visible only in one translation unit the recommended way is to put ii into an anonymous namespace. static works too, but it's use is discouraged as deprecated.

Link errorLNK2005 in VC++

I have a programme I which I want to implement button class. I have declared all my variable in button.h and defined all methods in button.cpp and I am calling these functions in WINMAIN the following error appears.
keylogger.obj : error LNK2005: "struct HBITMAP__ * hOldBmp" (?hOldBmp##3PAUHBITMAP__##A) already defined in Button.obj
The error is for multiple defination hOldBmp but It is only defined in button.h
"Only defined in button.h" is exactly your problem. Unless you declared it as extern there and put the definition into a C++ source file (not header file), every translation unit will get their own definition of the variable.
Seems like a common error: you include the implementation of this hOldBmp pointer from two .obj files, so from two cpp files. So both obj files contain code to implement this pointer. The linker cannot decide which implementation to use in the final binary.
Solution: leave only the declaration in the header file. You may declare it extern or make it a static member variable of the button class. Put the definition in the cpp file.

Resources