Jump to content
  • Advertisement
Sign in to follow this  
Jiia

Removing functions from builds

This topic is 4702 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This is a pretty simple question, but I've never actually seen it discussed before. Is there a nice way to remove a function-call completely from the release build of your application without using #ifdef type branches all over? Here's my simple, brute force method of doing this. This is a task-logging routine that much of my engine uses to track progression of tasks:
#ifdef _DEBUG
	VOID ScLog(Val_SystemLog type,const CHAR *Format,...);
#else
	inline VOID ScLog(Val_SystemLog type,const CHAR *Format,...) {}
#endif
Then of course, I have to #ifdef _DEBUG the actual implementation in the cpp module. I'm not even sure this will remove the function-call overhead, but I can't imagine why it wouldn't. Guess I could look at the ASM result. Anyway, are there better ways to accomplish this? If it seems like I'm asking a dumb question, I probably am. Please feel free to provide the dumb answer [wink]

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Andrew Russell
You know that no functions are inlined in debug builds anyway... Right?


He was inlining it when _DEBUG was not defined, not the other way around.

To the OP: I highly doubt there is a way other than using the preprocesser. That's what it's for, after all. You see this sort of thing in stardard libraries:

#ifdef _DEBUG
#define ASSERT(TEST) if(!(TEST)) { MessageBox(0, #TEST, "Assertion Failure", MB_OK | MB_ICONERROR); } else (void)0
#else
#define ASSERT(TEST)
#endif

Of course, empty macros like this will only work if either a)you're using a macro or b)the function it's replacing doesn't have any overloads or default values. If it has either, your method is better.
Quote:
I'm not even sure this will remove the function-call overhead, but I can't imagine why it wouldn't.

If your compiler doesn't remove the overhead when you're optimizing, you MUST get a new compiler.

Share this post


Link to post
Share on other sites
Quote:
Original post by ErzengeldeslichtesHe was inlining in when _DEBUG was not defined, not the other way around.


Exactly - he was pointing out that it was redundant.

Share this post


Link to post
Share on other sites
You could just #define ScLog(...) to remove the function call without the need for #ifdef. Or #define ScLog(Type, Format, ...) a macro to override the function call with "inline" code. In both of these options, the function still remains in the resulting object code, although its never called. This works because the preprocessor nabs the function call before the compiler tries to parse it. If you want to completely remove the function from existance, you'll have to wrap the function body in #ifdef ScLog/#endif. Otherwise, make sure you don't #define ScLog for the unit that contains the function body, otherwise you'll end up with something like this:

VOID ScLog(Val_SystemLog type,const CHAR *Format,...) {
// code goes here
}

...becomes...

VOID {
// code goes here
}

[Edited by - dcosborn on July 9, 2005 8:30:43 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Nitage
Quote:
Original post by ErzengeldeslichtesHe was inlining in when _DEBUG was not defined, not the other way around.


Exactly - he was pointing out that it was redundant.


No, he said "no functions are inlined in debug builds". How is this pointing out redundancy? In the debug build, the OP is not inlining, the function actually provides code. However, in the release build (when inling is useful) he inlines an empty function (which the compiler would inline anyway, but on that note, ALL inline declarations are "redundant" (more irrelevant)--the compiler will do what it darn well pleases.)

Share this post


Link to post
Share on other sites
I don't know if you guys noticed, but when _DEBUG is not defined the function has an empty body (I think that's how it's called) there, so I guess that what the OP wants is that when in release mode, the function won't be called.

@OP: If you're using Microsoft Visual Studio compiler you should be able to do this:

#ifdef _DEBUG
VOID ScLog(Val_SystemLog type,const CHAR *Format,...);
#else
# define ScLog __noop
#endif


Click here for more info on the __noop intrinsic.

Share this post


Link to post
Share on other sites
Quote:
Original post by Erzengeldeslichtes
Quote:
Original post by Nitage
Quote:
Original post by ErzengeldeslichtesHe was inlining in when _DEBUG was not defined, not the other way around.


Exactly - he was pointing out that it was redundant.


No, he said "no functions are inlined in debug builds". How is this pointing out redundancy? In the debug build, the OP is not inlining, the function actually provides code. However, in the release build (when inling is useful) he inlines an empty function (which the compiler would inline anyway, but on that note, ALL inline declarations are "redundant" (more irrelevant)--the compiler will do what it darn well pleases.)


Actually, I was working off the assumption that Jiia had simply removed the code from the {} to make his post shorter. So, given my assumption, I was correct [wink].


If there is no code to be run, his existing solution or Kamikaze15's or your own (Erzengeldeslichtes, for those people playing at home) is just fine. In theory, they should end up with same code (or lack thereof). This might not work if, say, you take the address of ScLog.

Jiia's original solution is nice to namespace as a plus. The other's have the advantage of giving 100% assurance that there will be no code generated.

Kamikaze15's has the negitive of being Microsoft-specific. Although the success of Jiia's original solution will also depend on the compiler.

Share this post


Link to post
Share on other sites
Wow, it looks like Microsoft built their __noop routine just for my situation. For readability sake, though, I would like it to be obvious as to what is happening. And it seems from the confusion of my post, my solution isn't very clear either.

As for the #define ScLog(...), will this actually work? I wasn't aware that macros could accept a variable argument list? A macro was my first guess to this problem, and that was what prevented me from using it in this function's situation.

Lastly, regarding the inline keyword. I don't see how it's use is redundant at all. How else could it be done? If I define the function body without the keyword, empty or not, in the header file, the compiler will have a fit. The resulting code would be included in every module that contains it. Is this incorrect?

And thanks for the advice.

edit:
Just to prevent further confusion, my goal really is to remove the function body. So what you see in my original post is the actual code. Including the empty {} and the ,... argument format. Those are not lazy posting placeholders :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!