C++ Prevent indenting when using a macro without a semicolon.

We use an ensure macro that skips a block of code if the ensure fails. We can chain together individual conditions so that logging can print the exact condition that failed, and allowing the debugger to break on that condition. An example might be this:

ENSURE_BLOCK(PointerThatMightBeNull)
ENSURE_BLOCK(SomeVariable >= 0)
ENSURE_BLOCK(File.IsOpen())
{
	// Everything is valid, run code.
}

These macros essentially just expand out to if(condition) { debug stuff } else therefore they don't end in a semicolon. Rider formats these as nested blocks without braces, like this:

ENSURE_BLOCK(PointerThatMightBeNull)
	ENSURE_BLOCK(SomeVariable >= 0)
		ENSURE_BLOCK(File.IsOpen())
		{
			// Everything is valid, run code.
		}

This formatting makes sense, but we want these macros to be aligned like in the first code snippet. Is there a way to prevent indenting of blocks without braces entirely? We always use braces for block statements that start on a new line, even if that block is a single statement, so disabling this indenting would fix the issue above and affect nothing else.

I couldn't seem to find anything in Settings > Editor > Code Style > C++ > Indentation and Alignment, which is where I would expect it to be. I also checked Braces Layout but that only seems to be related to situations where braces are present.

0
1 comment

Hello Charliew,

Thank you for contacting Rider support. This is by design and avoiding this might be tricky. 

Rider builds and uses Abstract Syntax Tree to express formatting. And it respects macro expansions. This indentation happens because the macro contains dangling ‘else’. The code on the line next to ‘else’ is logically indented. 

I understand why you want to prevent this from happening. However, I can't offer anything better than a workaround.

I mentioned a couple of available options here: https://github.com/dkjb634/ENSUREBLOCK_allign

There is a demo recording that demonstrates the suggested workaround. 

One more available option is to use ENSURE_BLOCK_DOUBLE(condition1, condition2) (TRIPLE, QUADRO, etc..) macros instead of multiple usages of ENSURE_BLOCK. For example:

#define ENSURE_BLOCK_DOUBLE(condition1, condition2) \
	bool bGo = true;\
	if(condition1){\
	std::cout << "Error: " << #condition1 << std::endl;\
	bGo = false;\
	}\
	if(condition2){\
	std::cout << "Error: " << #condition2 << std::endl;\
	bGo = false;\
	}\
	if(!bGo) std::cout<<"One of conditions is false"<<std::endl; else
	
...

ENSURE_BLOCK_DOUBLE(true, true)
{
}

Hope that helps. Have a nice day!

0

Please sign in to leave a comment.