# Removing functions from builds

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

## 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 on other sites
You know that no functions are inlined in debug builds anyway... Right?

##### Share on other sites
Quote:
 Original post by Andrew RussellYou 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 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 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 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 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

##### 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 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?

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 on other sites
As long as we're talking compiler specific options, some advice for the gcc users.

1. 1
2. 2
3. 3
Rutin
13
4. 4
5. 5

• 26
• 11
• 9
• 9
• 11
• ### Forum Statistics

• Total Topics
633700
• Total Posts
3013418
×

## Important Information

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!