What does DEBUG do?
My book talks about it, but I really don't understand what the point is in having the program debug.
What does DEBUG do?
My book talks about it, but I really don't understand what the point is in having the program debug.
If you decide to define this variable then whatever is enclosed in the #ifdef / #endif blocks will be compiled. Otherwise not. You can define it by including #define DEBUG at the top (in the source code), or as a flag in the compile parameters I believe. So you don't have to physically alter the source file.
Presumably these #ifdef / #endif blocks contain diagnostic code that's used to output descriptive messages to help trace and verify the program's execution.
You can have debug code that is compiled, or not, depending on if the constant "DEBUG" is defined (for example printing debug info). The actual name is not important really the interesting part is the #ifdef part (short for #if defined) which just asks if the constant following is defined, if it is, the code until the #endif mark is also compiled.
You can define this when you compile (for gcc and clang with the -D flag) and decide if you want to compile with or without the code included in these #ifdef clauses. Example:
If you compile this with (in case of gcc or clang at least): gcc -DRANDOM_NAME foo.c then the value of i will be printed, if you leave it out as in: gcc foo.c then nothing will get printed.Code:#include <stdio.h> int main() { for(int i = 0; i < 10; i++) { #if defined RANDOM_NAME printf("%d\n", i); #endif } return 0; }
So it allows you to compile two different versions depending on if you define the constant or not.
Last edited by Subsonics; 01-21-2013 at 01:34 PM.
DEBUG sounds like it's a name of an arbitrary preprocessor macro being defined. To see how it works it's best to consider a simple example. This program calculates the area of a rectangular region, and prints "debugging messages" if the macro DEBUG is defined:
Most compilers let you compile with a specific symbol defined. So if you compile with gcc usingCode:void printd(const char *msg) { #ifdef DEBUG printf("%s", msg); #else (void)msg; // ignore msg #endif } int main(void) { printd("main: Starting the program\n"); printd("main: Calculating the area\n"); double area = 2.84 * 5.67; printd("main: Printing the area\n"); printf("Area: %0.2f\n", area); return EXIT_SUCCESS; }
gcc -DDEBUG -o printarea printarea.c
The output will include the debugging messages. However if you decide you don't need the debugging messages anymore but want to keep them in the source code for reference purposes, then you simply recompile the same source file without defining that symbol
gcc -o printarea printarea.c
Of course, there are many ways to accomplish this. You mentioned putting one part in a separate source file. Yes, you could do that too. If you defined the "printd" function in two different versions, for example printd1.o and printd2.o, where one of them was the "do nothing version" and the other was the "debugging version", then linking your program with the version you want will produce a similar effect. In the end it all depends on how you want to organize your program. As programs grow you normally end up with several such defines and you tend to put them in a file called "config.h" or something similar. And then you modify that to change the build settings. DEBUG is just an arbitrary name chosen for one such setting.
There would be a chance that you put it back in your code incorrectly if you are copying and pasting - Especially if you are modifying code as you go.
There is something that does help you debug -> It's called "assert" and it works in a similar way.
Basically, you include assert.h - When you are making your program, you put asserts in to make sure all your assumptions are correct. (For example, in another thread (I can't remember which one) I have suggested that the OP asserts that a variable is never 0)
When the algorithm is working and you know it won't be 0, you define NDEBUG at the top of your code. All asserts are then optimised out of existence.
I'll give you an example if you wanted to get it working - Basically I've put in a few errors for you to find using the asserts. This little mess of a program was supposed to find the element in the array before '9' and print it out.
When you are confident that the program is working, you can define NDEBUG and all the asserts are optimised out of your code.Code:#include <stdio.h> #include <stdlib.h> #include <assert.h> int get_preceding(int arr[], size_t arr_size, int element); int main(void) { int my_arr[10] = {3, 6, 1, 4, 5, 2, 7, 8, 9, 10}; int i; for (i=0; i<15; i++) { int preceding_element; preceding_element = get_preceding(my_arr, sizeof(my_arr)/sizeof(*my_arr), i); if (my_arr[i]==9) { printf("%d", preceding_element); } } return EXIT_SUCCESS; } int get_preceding(int arr[], size_t arr_size, int element) { /* These asserts will automatically go when NDEBUG is defined */ assert(arr != NULL); assert((element - 1) >= 0); assert(element < arr_size); /* This section has been manually designated to go when NDEBUG is defined via the line below (finishes at #endif) */ #ifndef NDEBUG // Once the program is running, I won't care about this... printf("(%d) ", arr[element - 1]); #endif return arr[element - 1]; }
I like to make all my debug stuff around the define of NDEBUG -> That way it fits in nicely with the assert library.
[edit]
I forgot to say
#ifndef -> "if not defined"
[/edit]
[edit]
I reread the post and decided that it needed a few comments
[/edit]
Last edited by Click_here; 01-21-2013 at 08:38 PM.
Fact - Beethoven wrote his first symphony in C