Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to slip a static_assert into an expression in ISO C++11?

Tags:

In C++11 it is legal to write, for instance:

int b = (some_function_returning_void(), 1020); 

And you'll get back 1020. But it won't let you write:

int b = (static_assert(2 > 1, "all is lost"), 304); 

The documentation explains the legal spots where static_assert (a keyword, apparently) can occur:

A static assert declaration may appear at block scope (as a block declaration) and inside a class body (as a member declaration)

Just for the heck of it I tried a couple things until this worked:

int b = ({static_assert(2 > 1, "all is lost"); 304;}); 

But with -Wpedantic I get "warning: ISO C++ forbids braced-groups within expressions". Interestingly, these are called "statement expressions" and used in the Linux kernel.

But let's imagine I want to stay -Wpedantic. Are there any clean workarounds?

like image 416
HostileFork says dont trust SE Avatar asked Jul 09 '15 08:07

HostileFork says dont trust SE


People also ask

Where to put static assert?

Unlike #error, assertion using static_assert takes place after the preprocessing translation stage.

What is_ static_ assert?

The _Static_assert is a keyword defined in the C11 version of C. It evaluates a constant expression at compile-time and compares the result with 0. The _Static_assert is available as the macro static_assert keyword defined in C11. Click here for more information on static_assert.


2 Answers

As @dyp mentioned in the comments, you can abuse the comma operator and a lambda-expression :

([]{static_assert(true,"");}, 42) 

Live on Coliru

like image 138
Quentin Avatar answered Oct 23 '22 19:10

Quentin


static_assert is not an expression (unlike sizeof), so you can't use it where an expression would be required.

It's not even an expression with type void (interestingly, throw is an expression of type void) so you can't even use it in a ternary.

Statement expressions are not standard C++ so I'd advise against using them.

A lambda

int b = []{     static_assert(2 > 1, "all is lost"); return 304; }(); 

or

int b = ([]{static_assert(2 > 1, "all is lost");}, 304); 

is hardly clean. (The second lambda looks like a hair's-breadth away from being undefined).

like image 44
Bathsheba Avatar answered Oct 23 '22 19:10

Bathsheba