I have a VC++ application written using Visual Studio 2008. For debug purposes, timeout values compile differently depending on the type of build (Debug or Release). The code sample below is typical of how I am trying to do this.
#ifdef _DEBUG
if ( (dwObjectWaitState = ::WaitForSingleObject( m_hValidMsgRxdEvent, INFINITE )) != WAIT_OBJECT_0 )
#else
if ( (dwObjectWaitState = ::WaitForSingleObject( m_hValidMsgRxdEvent, BAS_THREE_SEC_TIMEOUT )) != WAIT_OBJECT_0 )
#endif
{
/* ... */
}
The Debug configuration has _DEBUG defined in the Preprocessor Definitions. The Release configuration does not have it. For each respective configuration, the expected lined is grayed out (presumably to indicate that the other line will be compiled in).
However, at run-time, the Release build timeouts remain INFINITE. When I try to set a breakpoint on both if statements and try to run the Release code, the breakpoint on the first if statement remains, whereas the other breakpoint gets moved down to the first line inside the brackets.
What gives? How do I make this compile option work? Should I be using something else?
Something like this instead perhaps?
#ifdef _DEBUG
#define NONMS_WAIT_TIMEOUT INFINITE
#else
#define NONMS_WAIT_TIMEOUT BAS_THREE_SEC_TIMEOUT
#endif
if ( (dwObjectWaitState = ::WaitForSingleObject( m_hValidMsgRxdEvent, NONMS_WAIT_TIMEOUT)) != WAIT_OBJECT_0 )
{
/* ... */
}
Edit: Debug builds in VS should have _DEBUG defined and release builds should have NDEBUG defined. Check your project pre-processor directives to make sure this is what you have.
Write it like this and build in the Release build:
#ifdef _DEBUG
#error Something is really wrong, _DEBUG is still defined
if ( (dwObjectWaitState = ::WaitForSingleObject( m_hValidMsgRxdEvent, INFINITE )) != WAIT_OBJECT_0 )
#else
if ( (dwObjectWaitState = ::WaitForSingleObject( m_hValidMsgRxdEvent, BAS_THREE_SEC_TIMEOUT )) != WAIT_OBJECT_0 )
#endif
Related
How do people trigger a breakpoint on gdb (for Cygwin, specifically) from the very source code?
Like when a JS script has the debugger word in it and Chromium dev tools trigger stop for debugging?
Here's how SDL2 implements this feature:
#if defined(_MSC_VER)
/* Don't include intrin.h here because it contains C++ code */
extern void __cdecl __debugbreak(void);
#define SDL_TriggerBreakpoint() __debugbreak()
#elif ( (!defined(__NACL__)) && ((defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))) )
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" )
#elif defined(__386__) && defined(__WATCOMC__)
#define SDL_TriggerBreakpoint() { _asm { int 0x03 } }
#elif defined(HAVE_SIGNAL_H) && !defined(__WATCOMC__)
#include <signal.h>
#define SDL_TriggerBreakpoint() raise(SIGTRAP)
#else
/* How do we trigger breakpoints on this platform? */
#define SDL_TriggerBreakpoint()
#endif
The conditionals should probably resolve to __asm__ __volatile__ ( "int $3\n\t" ) on Cygwin.
I am building my solution for x86 and x64 platforms.
Does Visual Studio have any target platform variables so I find which platform I am building for in compile time?
For example:
HINSTANCE hinstLib;
#ifdef TARGET_X86
hinstLib = LoadLibrary("32lib.dll");
#endif
#ifdef TARGET_X64
hinstLib = LoadLibrary("64lib.dll");
#endif
This is what I use:
#if defined(_MSC_VER)
// Microsoft VC compiler
# if defined(_WIN32)
# if defined(_WIN64)
// 64 bit windows
# else
// 32 bit windows
# endif
# endif
#endif
Note that _WIN32 is defined for 64 bit too.
Have a look here: http://msdn.microsoft.com/en-US/library/b0084kay.aspx
_WIN64 or _M_X64 should work.
So for your example:
HINSTANCE hinstLib;
#ifdef _WIN64
hinstLib = LoadLibrary("64lib.dll");
#else
hinstLib = LoadLibrary("32lib.dll");
#endif
The questions pretty simple. I want want a function (C++) or method which will, on call, returun something like
"Windows" //or
"Unix"
Nothing fancy, I dont need the version numbe or anything. Just the os name. A quick google searc didnt turn up anything useful, so I thought I'd post this here
Since you can not have a single binary file which runs over all operating systems, and you need to re-compile your code again. It's OK to use MACROs.
Use macros such as
_WIN32
_WIN64
__unix
__unix__
__APPLE__
__MACH__
__linux__
__FreeBSD__
like this
std::string getOsName()
{
#ifdef _WIN32
return "Windows 32-bit";
#elif _WIN64
return "Windows 64-bit";
#elif __APPLE__ || __MACH__
return "Mac OSX";
#elif __linux__
return "Linux";
#elif __FreeBSD__
return "FreeBSD";
#elif __unix || __unix__
return "Unix";
#else
return "Other";
#endif
}
You should read compiler's manuals and see what MACROS they provided to detect the OS on compile time.
From the Poco source code:
Win32:
std::string EnvironmentImpl::osNameImpl()
{
OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi);
if (GetVersionEx(&vi) == 0) throw SystemException("Cannot get OS version information");
switch (vi.dwPlatformId)
{
case VER_PLATFORM_WIN32s:
return "Windows 3.x";
case VER_PLATFORM_WIN32_WINDOWS:
return vi.dwMinorVersion == 0 ? "Windows 95" : "Windows 98";
case VER_PLATFORM_WIN32_NT:
return "Windows NT";
default:
return "Unknown";
}
}
Unix:
std::string EnvironmentImpl::osNameImpl()
{
struct utsname uts;
uname(&uts);
return uts.sysname;
}
#ifdef _DEBUG
// calls appropriate functions for message logging
#define LOGMESSAGE( stdStr ) gLogger.LogMessage( stdStr, __FILE__, __LINE__ );
// calls appropriate function for success logging
#define LOGSUCCESS( stdStr ) gLogger.LogSuccess( stdStr, __FILE__, __LINE__ );
// calls appropriate function for error logging
#define LOGFAILURE( stdStr ) gLogger.LogFailure( stdStr, __FILE__, __LINE__ );
#endif
#ifdef NDEBUG
// does nothing in release mode
#define LOGMESSAGE( stdStr )
// does nothing in release mode
#define LOGSUCCESS( stdStr )
// Logs failures in release mode
#define LOGFAILURE( stdStr ) gLogger.LogFailure( stdStr, __FILE__, __LINE__ );
#endif
Say I call the macros like the following
if ( SomeFunc() )
{
LOGSUCCESS("Success calling SomeFun()");
}
else
{
LOGFAILURE("Failure calling SomeFun()");
}
In release mode LOGSUCCESS is blank so does that mean "Success calling SomeFunc()" string isn't compiled into the code and won't exist in the compiled code, or is that left over, but the macro doesn't do anything with it?
EDIT:
I mean does it effectively leave the code like this in release mode?
if ( SomeFunc() )
{
"Success calling SomeFun()";
}
else
{
gLogger.LogFailure("Failure calling SomeFun()", __FILE__, __LINE__ );
}
or
if ( SomeFunc() )
{
}
else
{
gLogger.LogFailure("Failure calling SomeFun()", __FILE__, __LINE__ );
}
It will be expanded to -
if ( SomeFunc() )
{
; //Remember the semicolon here
}
else
{
gLogger.LogFailure("Failure calling SomeFun()", __FILE__, __LINE__ );
}
The macro resolution is a pre-compile time activity, which just replaces the definition into the code before compilation starts.
You have not associated any "meaning" to your debug dynamic information in the macro - so it is not used at all.
To put it in simple term, macro is just a "search and replace" kind of activity during pre-compilation. Now since the str is not defined in the macro, it is not "used". Since it is a kind of pre-compile time activity,the question of temporary variable does not arise.
I'm sure alot of you are aware of the macro
#ifdef DEBUG
#define DebugLog( s, ... ) NSLog( #"<%p %#:(%d)> %#", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DebugLog( s, ... )
#endif
This of course creates a function called DebugLog which you use in place of NSLog. Then when you change your project out of debug it will stop executing all of the NSLogs statements.
What I was thinking is is there a way to get this to work but with blocks. In other words I want to be able to do this:
DebugBlock(^{
//Code to only be executed while in Debug
});
Yes, I realize I can just do #ifdef DEBUG everywhere but that's not fancy enough for me :).
I feel kind of foolish about how simple it was but here is the solution.
#ifdef DEBUG
#define DebugBlock( ... ) dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ##__VA_ARGS__)
#else
#define DebugBlock( ... )
#endif
The the usage looks a little something like this:
DebugBlock(^{
int i = 12;
int b = 400;
int Answer = i+b;
NSLog(#"%d", Answer);
});
You can also change the dispatch type fo async if your heart desires.