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.
Related
This question already has answers here:
what does WINAPI stand for
(3 answers)
Closed 9 years ago.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
In the example shown it looks like the WinMain function has two return types?: "int" & "WINAPI"?
I'm not familiar with the syntax of what's going on here. Is "WINAPI" a return type or something else?
Found out it was a calling convention more information can be found at the link that Benjamin Lindley posted here: what does WINAPI stand for
WINAPI is not the return type, it's some microsoft bullshit.
wap
Excuse me, I meant to say that WINAPI is macro that actually evaluates to __stdcall.
Here is a question that is very similar to yours, with more details. Basically, these are compiler extensions. I believe gcc provides similar extensions via the attributes keyword.
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.
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.
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.
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.