How to use #ifdef _DEBUG on Linux? - c++

I have a problem with _DEBUG macro on Linux C++.
I tried to use something like this:
#ifdef _DEBUG
cout << "Debug!" << endl;
#endif
But it doesn't work when I select Debug in IDE. However it worked on Windows.
I use Eclipse IDE for C++ coding on Linux.

On windows you were probably using Visual Studio, which automatically defines the _DEBUG symbol when building the solution in Debug mode. Symbols are usually defined when invoking the compiler, and then they will be used during the pre-processor phase.
For example, if you are using GCC via command line and you want to re-use the _DEBUG symbol because you are handling an already established codebase, you can define it using the -D parameter via command line.
#include <iostream>
int main() {
std::cout << "Hello world!\n";
#ifdef _DEBUG
std::cout << "But also Hello Stack Overflow!\n";
#endif
return 0;
}
Compiling this with the following command line
g++ -D _DEBUG define.cpp
will give the following result
Hello world!
But also Hello Stack Overflow!
Your best bet for eclipse cdt however could be to modify the paths and symbols properties in the project properties.

If you use cmake put the following in your your top-level CMakeLists.txt file
set_directory_properties(PROPERTIES COMPILE_DEFINITIONS_DEBUG "_DEBUG")
found on CMake Mailinglist

Put #define _DEBUG somewhere north of where you have this snippet, or in your project settings.

Related

Is debugging code not going to production in c++? [duplicate]

Does #ifdef _DEBUG in the main function has any sense if I am working on visual studio 2013 ?
If yes, what it is for ?
int _tmain(int argc, _TCHAR* argv[])
{
#ifdef _DEBUG
//creating some objects, using functions etc;
#endif
}
#ifdef DEBUG or #ifdef _DEBUG are used to handle some code that you use for debugging purposes. If you add #undef _DEBUG or similar to this at the very beginning of your code, the compiler will skip the code contained in #ifdef DEBUG /* bla bla */ #endif.
If you're
//creating some objects, using functions etc;
inside this block and thinking this will work, I assure you, it won't until you include -D_DEBUG in compiler's options during invocation.
for example it can be used to do stuff only in debug compilation ;)
Check your flags specifically to VS, in linux for example, you add NDEBUG to non debug builds.. so check your project properties.. compile command line.. etc..

#ifdef _WIN32 not getting detected

I can not get the #ifdef rule to work at least on windows (64 bit).
Compiler version is g++ 5.4.0
I have tried:
#ifdef _WIN32
#ifdef _WIN64
#ifdef OS_WINDOWS
I have compiled the following test with:
g++ main.cpp
Even with a simple code as this:
#include <iostream>
int main()
{
std::cout << "you are on...";
#ifdef _WIN32
std::cout << "Windows" << std::endl;
#elif __linux__
std::cout << "Linux" << std::endl;
#endif
return 0;
}
Output is:
"you are on..."
...and nothing else gets couted out.
#ifdef _WIN32
#ifdef _WIN64
These are pre-defined macros defined by the MSVC compiler. You appear to be using g++ instead. That probably means either MinGW, or Cygwin.
Here and here are collections of macros pre-defined by several compilers.
MinGW __MINGW32__
Cygwin __CYGWIN__
If you prefer to not to build hefty ifdef - else trees, and scour the internet for macros defined by obscure compilers, and their different versions, I recommend to instead include a few headers from boost. They have already done the hard part of the work. Although, note that BOOST_OS_WINDOWS is separate from BOOST_OS_CYGWIN.
Use __CYGWIN32__ to detect Windows when compiling g++ in cygwin. (This is defined in both 32 and 64 bit).
_WIN32 &c. may not be defined in that case. It isn't for me.
(As also mentioned in a comment; using echo | g++ -dM -E to output the list of what is defined can be helpful.)
yes, it is true that this:
#ifdef _WIN32
sometimes doesn't work on Windows (!) In this case, use the following form instead:
#if defined(_WIN32)
I was surprised but I have seen that problem and it helped me!

CMake project for Eclipse+MinGW using Visual Studio defines instead of GCC

My problem is very much related the post
Defined macro not recognized
I wrote a CMakeLists file to be able to build my project for OS X (Eclipse mostly but sometimes used Xcode) and Windows (Visual Studio). The issue showed up today when creating my project for Windows + MinGW. I was using the defined _WIN32 to enable some functions when I was in windows, i.e.
bool Normal::HasNaNs() const
{
#ifdef _WIN32
return _isnan(x) || _isnan(y) || _isnan(z);
#else
return isnan(x) || isnan(y) || isnan(z);
#endif
}
However, with the combo Eclipse+MinGW the code is entering the ifdef part instead of (what I was hoping/thinking should be correct) entering the else part. I think Visual is the only one having the _isnan() function.
So, what would be a more robust way to check for Windows+VS, Windows+MinGW, OSX ?
_MSC_VER is the best way to check if you're being compiled by Visual Studio:
https://msdn.microsoft.com/en-us/library/b0084kay.aspx
For checking for MinGW (please see comment for more info), you can use:
#ifdef __GNUC__
#ifdef __MINGW32__
as per this answer:
https://stackoverflow.com/a/17493838/493106
and then __APPLE__ for os x.
https://stackoverflow.com/a/2166491/493106

GCC cross-compiler for VxWorks can't compile C++

I'm trying to port a Linux library to run on VxWorks. I have successfully built binutils and gcc to target i486-wrs-vxworks and I can successfully build a simple C program. However, when I try to compile C++, things break.
I have a simple Hello World program:
#include <string>
#include <iostream>
int main()
{
std::string s = "Hello World";
std::cout << s << std::endl;
return 0;
}
To build it, I call:
i486-wrs-vxworks-gcc -I/home/kyle/vxworks-6.9/target/usr/h -I/home/kyle/vxworks-6.9/target/usr/h/c++ hello.cpp
This always fails with the message:
In file included from /home/kyle/vxworks-6.9/target/usr/h/c++/cerrno:4:0,
from /home/kyle/vxworks-6.9/target/usr/h/c++/xlocnum:4,
from /home/kyle/vxworks-6.9/target/usr/h/c++/ios:4,
from /home/kyle/vxworks-6.9/target/usr/h/c++/ostream:4,
from /home/kyle/vxworks-6.9/target/usr/h/c++/istream:4,
from /home/kyle/vxworks-6.9/target/usr/h/c++/string:4,
from hello.cpp:1:
/usr/local/lib/gcc/i486-wrs-vxworks/4.6.4/../../../../i486-wrs-vxworks/include/yvals.h:4:24: fatal error: yvals.h: No such file or directory
If I go look inside /usr/local/i486-wrs-vxworks/include/yvals.h, this is what I see:
/* yvals.h values header for conforming compilers on various systems */
#if (defined(__cplusplus) && defined(__GNUC__))
/* GCC C++ has it's own yvals.h */
#include_next <yvals.h>
#else /* __cplusplus && __GNUC__ */
#ifndef _YVALS
#define _YVALS
#ifdef _NO_WINDRIVER_MODIFICATIONS
#include <stdarg.h>
#endif
...
It appears that there is another yvals.h that needs to be included, but I can't find it anywhere. Did I just fail at building gcc correctly, or is there a way to fix this?
Which version of VxWorks are you using for this?
I have a fuzzy recollection that when upgrading VxWorks versions in the past there was a syntax error in yvals.h that was I needed to work around and it was fixed in a subsequent version.
Also, you can get the gcc cross compiler pre-built from WindRiver. Just login to windriver.com/support with your licence number and head to "Downloads" for your product version.
I went through a recent cross compiling nightmare myself (not VxWorks related) except that instead of yvals.h, I was having grief with stddef.h. The problem turned out to be that I needed to specify the include paths for the system header files.
Here are the steps it took me to solve my error messages. Feel free to modify as appropriate.
Create a file foo.c
#include <stddef.h> /* The problem header file (yvals.h for you?) */
int main (void) {
return 0;
}
Compile it with your compiler of choice
$(CC) foo.c -E
Note the include paths it uses and set them as your system header file list using the
-isystem <include path>
option.
Hope this helps.

#ifdef _DEBUG release mode in vs 2008

There are some part of my project which don't function in release mode. I can check it by using printf and it doesn't print anything. I'll show you in this following code:
void SNKsomething::vGetState()
{
#ifdef SNK_STH
for(int i = 0; i < 2; i++)
{
printf("sth\n');
}
Additionally, SNK_STH is defined in files Globals.h as following
#ifdef _DEBUG // in Project properties
#define SNK_STH
#else
// .....
So, I don't see sth which I print it in release mode. I want to know that I have to do something about _DEBUG in project properties of VS-2008. don't I?
_DEBUG is a preprocessor macro. If you right click on properties and go to c/c++, preprocessor is one of the options.
Preprocessor definitions are different for release and debug. If you add SNK_STH to the release preprocessor macros you will see your printf.
If you want to see the code in both debug and release, consider pulling it out of the ifdef.
I've had problems with the _DEBUG Macro, what I found very usefull is the
IsDebuggerPresent function
which returns a boolean:
If the current process is running in the context of a debugger, the return value is nonzero.
If the current process is not running in the context of a debugger, the return value is zero.