Sign in to follow this  
floatingwoods

conditional statement + automatic clean-up in preprocessor command

Recommended Posts

floatingwoods    364

Hello,

 

I wish to have a conditional statement, followed immediately by an object instanciation that will automatic clean-up at the end of a scope, a little bit similar to following example:

if (conditionRealized)
{
    // do something
}

which effectively would translate into something like:

if (conditionRealized)
{
    DummyObject dummy(initializationType);
    // do something
}

in above example, the destructor of dummy can automatically clean-up various things.

I have to place such a construct into several hundreds of functions, and I wish to simplify the task with a preprocessor command, so that I will be able to write:

IF_CONDITION_REALIZED_THEN
{
    // do something
}

but above construct does obviously not work, since the scope comes after the preprocessor command.

I could use a preprocessor like:

#define IF_CONDITION_REALIZED_THEN if(conditionRealized) { DummyObject dummy(initializationType);

in order to write my code like:

IF_CONDITION_REALIZED_THEN
    // do something
}

but my code editor doesn't like this (puts wrong indents), and it looks ugly.

 

Any idea?

 

Or, to present my problem in a different light:

 

I have a condition, that if passed, needs to make sure something is executed at the end of the scope, similar to this example:

if (canLockOtherThreads())
{
    // do something
    unlockOtherThreads();
}
Edited by floatingwoods

Share this post


Link to post
Share on other sites
Zaoshi Kaba    8434

You can do that with for() loop that does only single cycle:

#define IF_CONDITION_REALIZED_THEN for(DummyObject dummy(initializationType); conditionRealized; conditionRealized = false)

though it'll modify conditionRealized variable.

Share this post


Link to post
Share on other sites

This also works:

#include <iostream>
using namespace std;

class Test
{
	public:
	Test(bool condition) : condition(condition)
	{
		if(condition)
		{
			std::cout << "if(condition) special init needs" << std::endl;
		}
	}
	
	~Test()
	{
		if(condition)
		{
			std::cout << "if(condition) special cleanup needs" << std::endl;
		}
	}
	
	operator bool() { return condition; }
	
	private:
	bool condition = false;
};

#define DoIf(cond) if(Test DoIf_test = Test(cond))

int main()
{
	std::cout << "Start of main" << std::endl;
	
	DoIf(true)
	{
		std::cout << "Inside condition A" << std::endl;	
	}
	
	DoIf(false)
	{
		std::cout << "Inside condition B" << std::endl;	
	}
	
	std::cout << "End of main" << std::endl;	
	
	return 0;
}

This is legal, afaik, but I'm not sure if the lifetime of assignments within conditionals is standardized.

Compilable example

 

Some static code analyzers will complain about assignments within if() statements as warnings, because it'll think you're actually wanting if(i == 0) but are accidentally using if(i = 0).

 

[Edit:] Uh, ninja'd by almost an hour. rolleyes.gif I had to refine and test my work several times before I got it working, initially going the lambda route which, while functional, had too many limitations and syntax messiness.

Edited by Servant of the Lord

Share this post


Link to post
Share on other sites
Vortez    2714

Why not just put that 'special condition' in the object destructor instead? blink.png

 

Or just code a normal function for that???

Edited by Vortez

Share this post


Link to post
Share on other sites
ChaosEngine    5185
Just a note that all the above suggestions (the for loop back, etc.) are not exception safe.

As a general rule, I'd advise against this kind of macro. It's non-idiomatic, error prone and difficult to debug.

C++ already has a perfectly valid cleanup mechanism in RAII. Trust me, saving a bit of typing is just not worth it

Edit: oops, missed servants post. That is exception safe, still wouldn't use the macro though.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this