Using UNREFERENCED_PARAMETER macro - c++

I'm using \W4 warning level on Visual Studio and I'm writing a Windows program.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
All these parameters are not used in my application, so I get warnings at compile time.
I know there are two ways of dealing with this:
Commenting parameters HINSTANCE /*hInstance*/ ...
Using the UNREFERENCED_PARAMETER macro
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
UNREFERENCED_PARAMETER(hInstance);
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
Which one is the correct one? Which one is the safer to use? Are there any problems with using the macro?

I would prefer commenting the parameters.
The macro UNREFERENCED_PARAMETER is defined in winnt.h and therefore not portable.
And if later you do reference it, you might overlook to remove the macro.
Edit: With C++17 you can now use the [[maybe_unused]] attribute. This is useful for code depending on preprocessor macros:
void foo( [[maybe_unused]] int value )
{
#ifdef USE_VALUE
useValue(value);
#endif
}
Now there won't be warnings even if USE_VALUE is undefined.

I consider the name-removing version the first to go with. It can have a disadvantage to confuse the information system so tooltip shows the crippled version. But healthy ones would use the declaration, where the names are there. (and for static and one-use things you should not have unused params, right?)
Otherwise it's matter of taste really.

In C++, both are the correct ways to handle and do not introduce any unsafe-ness directly. However, the use of UNREFERENCED_PARAMETER can cause a maintenance issue because you need to remove the use of the macro if the parameter is used in the future updates, yet compilers do not warn that situation. To audit correct use of the macro, developers have to manually inspect that the parameters are still unused.
As others pointed out, cross-platform portability could be an issue too.
In C, it is not possible to remove the parameter name; hence the macro is the reasonable solution on the Windows platform, especially in Win32 programming.

Related

Stack around the variable was corrupted when using code from library

I'm using log4cplus library. When I build application, it compiles and runs properly (well, not quite properly since it's not logging anything, but that's the other issue), but when I close it, I'm getting this error:
Run-Time Check Failure #2 - Stack around the variable 's1' was corrupted.
Here is my code. I marked relevant places with comments.
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow) {
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
////////////////// SET UP CHECKS FOR MEMORY LEAKS ////////////////////
_CrtMemState s1;
_CrtMemCheckpoint(&s1);
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
//////////////////////////////////////////////////////////////////////
log4cplus::PropertyConfigurator config(_T("log.properties")); // <-- this line seems to be responsible for the issue. When I remove it, everything is ok.
_CrtMemDumpAllObjectsSince(&s1); // <-- here program breaks with mentioned error.
return 1;
}
So, as written in comments, PropertyConfigurator() constructor seems to be responsible for the problem. Not any other code in this place causes the same problem.
I wonder what could be wrong if this library is used by many people and it works, while I have problems with stack corruption.
Does anyone have any idea of what's going on in here?
EDIT:
I removed all unnecessary code (the code above is edited) and left only the relevant. Still log4cplus::PropertyConfigurator config(_T("log.properties")); seems to cause the issue.
This error Run-Time Check Failure #2 is generally caused by an error somewhere in memory. After looking at the sample you provided you should change this:
log4cplus::PropertyConfigurator config(_T("log.properties"));
to this:
log4cplus::PropertyConfigurator configure(_T("log.properties"));
If that does not help then start looking at initializations of memory.

'expected primary expression before ')' error'

I am making a game engine and I keep getting an error whenever I compile the project. The compiler spits out this error:
expected primary expression before ')' token.
Can anyone help me with this? I will provide the line with the error below.
if (GameInitialize(HINSTANCE))
You need to pass a value as the parameter when you call the function. At least in Windows, HINSTANCE is defined as a type (and I doubt anything but Windows uses that name).
Typical use would be in WinMain, which receives the HINSTANCE of the current process as a parameter:
int WinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow) {
// ...
if (GameInitialize(hInstance))
// whatever
}
Note that C++ (like C) is case sensitive, so hInstance and HINSTANCE aren't the same, even though they're equal in a case-insensitive comparison. This is often problematic for people who've used languages (e.g., Pascal) that are normally case-insensitive.

What is the point of defining a calling convention?

For example:
int WINAPI WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show )
WINAPI is a a define that looks like this:
#define WINAPI __stdcall
why can't you just do:
int __stdcall WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show )
actually I think my problem is that I'm sort of confusing defines with typedef's. Can someone explain this to me? what does the define do and why can't you just write __stdcall in its place?
Because the WINAPI calling convention is not guaranteed to be __stdcall. Code that uses WINAPI will still be correct even when it isn't.
You can write the function as in your latter example, and it'd work fine - it's just not good practice and would not be portable to a platform where the calling convention is something else.
This was originally done during the switchover from 16-bit to 32-bit code. In the 16-bit version of <windows.h> it was:
#define WINAPI __pascal
WINAPI let you compile for either without modifying the source code. Of course, 16-bit Windows is no longer a factor (at least for most people), but it's still not worth changing all the source code to use __stdcall directly (especially since it could change again someday).
You can just write __stdcall in its place, but don't. They've seen fit to #define WINAPI to __stdcall to make that opaque, which is just good programming practice.
Also, back in the day, some Windows libraries used Pascal calling convention and other libraries used C convention. A preprocessor define helped gloss over that.
Because WINAPI is a macro (well a #define anyway) it can be "pre-processed" to mean something else or even nothing at all.
That means you can write more portable code, as you can put in WINAPI when it is required by Win32 to mean __stdcall but, or if it is required in another environment to mean something else or nothing.

What does "WINAPI" in main function mean?

Could you please explain to me the WINAPI word in the WinMain() function?
In the simplest way..
#include <windows.h>
int -->WINAPI<-- WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MessageBox(NULL, "Goodbye, cruel world!", "Note", MB_OK);
return 0;
}
Is it just some Windows funky mode?
What does it do? Or rather what is this C++ feature I haven't encountered yet?
WINAPI is a macro that evaluates to __stdcall, a Microsoft-specific keyword that specifies a calling convention where the callee cleans the stack. The function's caller and callee need to agree on a calling convention to avoid corrupting the stack.
WINAPI is a macro that expands to __stdcall which means that the callee cleans the stack.
This is a macro definition intended to denote the Windows calling convention. From MSDN:
The way the name is decorated depends
on the language and how the compiler
is instructed to make the function
available, that is, the calling
convention. The standard inter-process
calling convention for Windows used by
DLLs is known as the WinAPI
convention. It is defined in Windows
header files as WINAPI, which is in
turn defined using the Win32
declarator __stdcall.
It's Windows-specific. It specifies the calling convention. WinMain gets called by Windows, and this ensures that the caller and callee agree on the calling convention.

Using inline assembly from c++

Just to experiment assembly in C++, I tried the following, which is causing the application to crash:
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
__asm {
push 5000
call Sleep
}
...
}
the assembly part of code is supposed to act like the following line
Sleep(5000);
What am I doing wrong?
edit: I am getting an Access Violation.
I just checked the assembly code in VC++ 6.
You have to call the routine like this:
call dword ptr [Sleep]
Write the code in straight in C - disassemble it, figure out what the compiler does, then you can write a correct version -
I am not x86 guy, but I think you should check the calling convention used by the compiler. It seems that Sleep cleans after it self, so maybe the compiler is inserting cleaning code also after that?
It's been a long time since I did this but I recall from the past that sometimes I had to put a single parameter in the EAX register rather than push it on the stack. Or perhaps you need to pop it off again after words if the calling convention requires it.
As Arak says, check that you are matching the compiler calling convention. Masm will force one convention, check your C compiler is enforcing the same.