472,787 Members | 1,552 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,787 software developers and data experts.

Conditional code

Lets say you have a function "debug printf" which works like printf but will
get left out if _DEBUG flag is not defined along with the strings which are
to be printed.

Now I defined this:

#ifdef _DEBUG
void dbgprintf(char *szFormat, ...);
#else
#define dbgprintf
#endif

This works fine but under some compilers eg. gcc it will give me a huge
bunch of warnings saying the statement has no effect. This is ofcourse true,
but I don't need to be reminded since this was the intention. Does any of
you have good ideas how I can improve the macro to stop the compiler from
giving this?

Thanks in advance.
-- John
Jul 23 '05 #1
16 2377

"John Smith" <jo********@x-formation.com> wrote in message
news:42*********************@dread11.news.tele.dk. ..
Lets say you have a function "debug printf" which works like printf but will get left out if _DEBUG flag is not defined along with the strings which are to be printed.

Now I defined this:

#ifdef _DEBUG
Note that the above name is reserved for the implementation in ISO C++,
since it begins with an underscore and a capital letter. I guess this is ok
if you are making use of the compilers built-in debug flags, but I would
recommend against it. I always just define DEBUG or MY_DEBUG when I want to
do something like this example, and that works just fine.
void dbgprintf(char *szFormat, ...);
#else
#define dbgprintf
#endif

This works fine but under some compilers eg. gcc it will give me a huge
bunch of warnings saying the statement has no effect. This is ofcourse true, but I don't need to be reminded since this was the intention. Does any of
you have good ideas how I can improve the macro to stop the compiler from
giving this?


I don't understand why you would see more than one error message ... are you
using include guards on your headers (I assume the above appears in exactly
one header file somewhere in your program.

In any case, why not just write:
// ...
#else
#define dbgprintf /**/

or something like that?

HTH,

Dave Moore
Jul 23 '05 #2
"John Smith" <jo********@x-formation.com> wrote in message
news:42*********************@dread11.news.tele.dk. ..
Lets say you have a function "debug printf" which works like printf but will get left out if _DEBUG flag is not defined along with the strings which are to be printed.

Now I defined this:

#ifdef _DEBUG
void dbgprintf(char *szFormat, ...);
#else
#define dbgprintf
#endif


1. You could use in your code

dbgprintf("Print this string");

and define

#ifdef _DEBUG
void dbgprintf(whatever_arguments ...)
{
printf(...
}
#else // #ifdef _DEBUG
void dbgprintf(whatever_arguments ...)
{
// Do nothing.
}
#endif // #ifdef _DEBUG

2. Personally, I'm apprehensive about this approach at all. Consider the
following
dbgprintf("%d", my_terribly_expensive_operation());
or
dbgprintf("%d", my_operation_with_various_side_effects());

Then the compiler would call my_terribly_expensive_operation() or
my_operation_with_various_side_effects() even in release mode - probably not
what I want.
So I usually define dbgprintf as a macro itsel - this way the compiler can
eleminate its arguments completely.

3. Another matter which is possibly personal taste - it might be better to
distinguish between debug and trace: the first checks internal invariants;
the second outputs diagnostic information. Personally, I think these should
be orthogonal. There are cases where I find bugs in release mode only (e.g.,
because of thread races, which debug mode can change entirely). At the very
least, I usually try to have orthogonal debug and trace macros.
Jul 23 '05 #3
John Smith wrote:

This works fine but under some compilers eg. gcc it will give me a huge
bunch of warnings saying the statement has no effect.


Turn off the warning. You know better than some anonymous compiler
writer whether your code does what you meant it to do.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 23 '05 #4
> Note that the above name is reserved for the implementation in ISO C++,
since it begins with an underscore and a capital letter. I guess this is ok if you are making use of the compilers built-in debug flags, but I would
recommend against it. I always just define DEBUG or MY_DEBUG when I want to do something like this example, and that works just fine.
Actually it's from Microsoft Compilers which sets that symbol. I just reused
it. The only thing I can say is that if people will have problems with it in
future, I won't be the only one.

I don't understand why you would see more than one error message ... are you using include guards on your headers (I assume the above appears in exactly one header file somewhere in your program.

Yes I have include guards. I'm sorry I wasn't telling the whole story. The
reason for having multiple warnings is just because I call dbgprintf()
multiple times in my code.
In any case, why not just write:
// ...
#else
#define dbgprintf /**/

or something like that?


Well I do that... and it works. But thats what gives warnings.
Assume we use it:

....
dbgprintf("test\n");

after the macro expansion it will look like:

("test\n");

and thus the code is not doing anything meaningful and I get the warning.

-- John
Jul 23 '05 #5
John Smith wrote:
Lets say you have a function "debug printf" which works like printf but will
get left out if _DEBUG flag is not defined along with the strings which are
to be printed.

Now I defined this:

#ifdef _DEBUG
void dbgprintf(char *szFormat, ...);
#else
#define dbgprintf
#endif

This works fine but under some compilers eg. gcc it will give me a huge
bunch of warnings saying the statement has no effect. This is ofcourse true,
but I don't need to be reminded since this was the intention. Does any of
you have good ideas how I can improve the macro to stop the compiler from
giving this?
...


I hope you understand that when '_DEBUG' is not defined the statement

dbgprintf("%d %d %d", a, b, c);

turns (after preprocessing) into

("%d %d %d", a, b, c);

i.e. it is not completely left out. This is a completely different
statement with completely different semantics. In many cases it will
have no effect (which is what the compiler is trying to tell you), but
is it actually what you wanted to do?

--
Best regards,
Andrey Tarasevich
Jul 23 '05 #6
> I hope you understand that when '_DEBUG' is not defined the statement

dbgprintf("%d %d %d", a, b, c);

turns (after preprocessing) into

("%d %d %d", a, b, c);

i.e. it is not completely left out. This is a completely different
statement with completely different semantics. In many cases it will
have no effect (which is what the compiler is trying to tell you), but
is it actually what you wanted to do?


Actually yes it is. I'd rather get it removed all together. The idea is to
print out when in debug mode and leave the code out in release mode
(including the string to print).
Another guy suggested to make a dummy function which does nothing but it's
not suitable to me since the strings are still left in.

if the function had known arguments I could just make a dummy like:
#define dbgprintf(a,b,c)

but since it uses varargs I'm not sure how to create such a macro which
satisfies it.

The alternative would be like manually declare each line:

#ifdef _DEBUG
printf("we are in debug mode now\n");
#endif

But this takes 3 lines of code whereas dbgprintf() only takes 1.

Any ideas?

Thanks.
-- John
Jul 23 '05 #7
In any case, why not just write:
// ...
#else
#define dbgprintf /**/

or something like that?


Well I do that... and it works. But thats what gives warnings.
Assume we use it:

...
dbgprintf("test\n");

after the macro expansion it will look like:

("test\n");


ROFL .. I was wondering what on earth you were talking about until I looked
closely at my earlier suggestion .. what I meant was:

#else
#define dbgprintf //

that way whatever the args of dbgprintf are, they will be turned into a
comment. I knew I had used comments previously to deal with this, but I
didn't remember exactly how. Sorry for the confusion.

HTH,

Dave Moore
Jul 23 '05 #8
John Smith wrote:
I hope you understand that when '_DEBUG' is not defined the statement

dbgprintf("%d %d %d", a, b, c);

turns (after preprocessing) into

("%d %d %d", a, b, c);

i.e. it is not completely left out. This is a completely different
statement with completely different semantics. In many cases it will
have no effect (which is what the compiler is trying to tell you), but
is it actually what you wanted to do?


Actually yes it is. I'd rather get it removed all together. The idea is to
print out when in debug mode and leave the code out in release mode
(including the string to print).


There is another rather well-known approach. Define your macro as

#ifdef _DEBUG
void dbgprintf_(char *szFormat, ...);
#define dbgprintf(p) dbgprintf_ p
#else
#define dbgprintf(p)
#endif

and use it as follows

dbgprintf(("%d %d %d\n", a, b, c));

(note the double parenthesis). In this case everything will be left out
in non-debug version, but you have to use '(())', which makes it look a
little inelegant.

--
Best regards,
Andrey Tarasevich
Jul 23 '05 #9
Dave Moore wrote:

ROFL .. I was wondering what on earth you were talking about until I looked
closely at my earlier suggestion .. what I meant was:

#else
#define dbgprintf //

that way whatever the args of dbgprintf are, they will be turned into a
comment. I knew I had used comments previously to deal with this, but I
didn't remember exactly how. Sorry for the confusion.
...


This might work with some compilers, but won't work in general. In C++
the comments are fully processed (and replaced with whitespace) before
the preprocessor has a chance to do its thing. The compiler is free to
assume that preprocessor doesn't generate any new comments.

--
Best regards,
Andrey Tarasevich
Jul 23 '05 #10
> ROFL .. I was wondering what on earth you were talking about until I
looked
closely at my earlier suggestion .. what I meant was:

#else
#define dbgprintf //


Good idea but unfortunatly gcc wasn't fooled by it. It just ignores the
comment and continues with the warnings.
Too bad.

-- John
Jul 23 '05 #11
>
Turn off the warning. You know better than some anonymous compiler
writer whether your code does what you meant it to do.

Yes that will be my last way out if I don't find a better way. As suggested
in other threads the codes isn't removed completely so theres still room for
alternate improvements.

Unfortunatly gcc doesn't spit out error codes like some other compilers
does, so it's a little harder to be sure you turn off a specific warning
message.

-- John
Jul 23 '05 #12
"John Smith" <jo********@x-formation.com> wrote in message
news:42*********************@dread11.news.tele.dk. ..
ROFL .. I was wondering what on earth you were talking about until I

looked
closely at my earlier suggestion .. what I meant was:

#else
#define dbgprintf //


Good idea but unfortunatly gcc wasn't fooled by it. It just ignores the
comment and continues with the warnings.
Too bad.


Herb Sutter explains the reason at the end of the following article:

http://www.gotw.ca/gotw/077.htm

Ali

Jul 23 '05 #13
"Dave Moore" <dt*****@email.unc.edu> schrieb im Newsbeitrag news:36*************@individual.net...
#define dbgprintf //

that way whatever the args of dbgprintf are, they will be turned into a
comment.


Not a good idea. Even if it would work, it would only work with single line statements. Something like

dbgprintf("....",
arg1,
arg2,
//...
);

would most likely cause a compilation error.

Heinz
Jul 23 '05 #14

"Heinz Ozwirk" <ho**********@arcor.de> wrote in message
news:42***********************@newsread4.arcor-online.net...
"Dave Moore" <dt*****@email.unc.edu> schrieb im Newsbeitrag
news:36*************@individual.net...
#define dbgprintf //

that way whatever the args of dbgprintf are, they will be turned into a
comment.


Not a good idea. Even if it would work, it would only work with single line
statements. Something like

dbgprintf("....",
arg1,
arg2,
//...
);

would most likely cause a compilation error.

Heinz

Well .. I never used my homemade debug utility that way so it never came up
.... what worries me more is that now it doesn't work properly anymore, at
least not on g++. I can't remember for sure what platform I initially used
the trick on (Metrowerks I think). Bummer ... I liked it because it was so
simple and didn't rely on any "macro magic", which I find frightening. I
guess I will have to implement one of the other strategies posted here if I
have a need for such a "trick" again in the future.

Thanks for straightening me out y'all.

Dave Moore
Jul 23 '05 #15
What about this version:

#ifdef _DEBUG
statid void debugprintf_(const char *, ...) {}
#define debugprintf debugprintf_
#endif

So in debug mode all calls to debugprintf will be translated to
debugprintf_, and that function then does nothing.

This method has the advantage/disadvantage that all the arguments to
debugprintf will always be evaluated. This is good because it saves you
from error caused by missing side effects of arguments no evaluated in
the release version, but is also bad because you waste cpu time in the
release mode.

harald

Jul 23 '05 #16
John Smith wrote:
Lets say you have a function "debug printf" which works like printf but
will get left out if _DEBUG flag is not defined along with the strings
which are to be printed.

Now I defined this:

#ifdef _DEBUG
void dbgprintf(char *szFormat, ...);
#else
#define dbgprintf
#endif

This works fine but under some compilers eg. gcc it will give me a huge
bunch of warnings saying the statement has no effect. This is ofcourse


You can use something like this:

#else
inline void dbgprintf_do_nothing_version_with_ugly_name (char *, ...) { }
#define dbgprintf dgbprintf_do_nothing_version_with_ugly_name
#endif

--
Salu2
Jul 23 '05 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: neblackcat | last post by:
Would anyone like to comment on the following idea? I was just going to offer it as a new PEP until it was suggested that I post it here for comment & consideration against PEP 308. I'm far...
28
by: Benjamin Niemann | last post by:
Hello, I've been just investigating IE conditional comments - hiding things from non-IE/Win browsers is easy, but I wanted to know, if it's possible to hide code from IE/Win browsers. I found...
13
by: Andrew | last post by:
I use conditional compiler constants, set through the VBA IDE in Tools, <projectname> Properties, that I refer to throughout my code to control which code is used during development, and which...
4
by: Bradley | last post by:
I have an A2000 database in which I have a continuous form with a tick box. There is also a text box with a conditional format that is based on the expression , if it's true then change the...
2
by: Megan | last post by:
Can you write conditional VBA code that affects only one or two records on a continuous subform? I have a form with a subform on it. The parent/ child field that links the forms is CaseID. The...
1
by: chris han | last post by:
Hi, all, I'm trying to use Conditional Compilation Statements in my code. using System; #define DEBUG public class MyClass { public static void Main() {
10
by: John Smith | last post by:
After reading C# documentation the Conditional attribute seemed the way to go, but after inspecting the IL it seems those methods are still there and I imagine the CLR removes them. Using #if DEBUG...
8
by: Typehigh | last post by:
I have many text fields with conditional formatting applied, specifically when the condition is "Field Has Focus". Without any events associated with the fields the conditional formatting works...
5
by: paulo | last post by:
Can anyone please tell me how the C language interprets the following code: #include <stdio.h> int main(void) { int a = 1; int b = 10; int x = 3;
7
by: Frank Munsberg | last post by:
Hi There, I'm currently in a mild state of confusion about the Conditional Attribute. The code below is taken from the implementation of "Design By Contract" that I've put in somewhere in my...
0
by: Rina0 | last post by:
Cybersecurity engineering is a specialized field that focuses on the design, development, and implementation of systems, processes, and technologies that protect against cyber threats and...
0
by: erikbower65 | last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps: 1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal. 2. Connect to...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
0
by: Taofi | last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same This are my field names ID, Budgeted, Actual, Status and Differences ...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: lllomh | last post by:
How does React native implement an English player?
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.