Why Are Empty Expressions Legal in C/C++

Why are empty expressions legal in C/C++?

This is the way C and C++ express NOP.

C++: why is iter++-empty() legal?

Per cppreference, ++ and -> have the same precedence and have left to aright associativity. That means that iter++ is executed first, and then ->empty() is applied to the result of iter++, which is just iter (from before the increment) since it is postfix increment.

Why are statements with no effect considered legal in C?

One benefit to allowing such statements is from code that's created by macros or other programs, rather than being written by humans.

As an example, imagine a function int do_stuff(void) that is supposed to return 0 on success or -1 on failure. It could be that support for "stuff" is optional, and so you could have a header file that does

#if STUFF_SUPPORTED
#define do_stuff() really_do_stuff()
#else
#define do_stuff() (-1)
#endif

Now imagine some code that wants to do stuff if possible, but may or may not really care whether it succeeds or fails:

void func1(void) {
if (do_stuff() == -1) {
printf("stuff did not work\n");
}
}

void func2(void) {
do_stuff(); // don't care if it works or not
more_stuff();
}

When STUFF_SUPPORTED is 0, the preprocessor will expand the call in func2 to a statement that just reads

    (-1);

and so the compiler pass will see just the sort of "superfluous" statement that seems to bother you. Yet what else can one do? If you #define do_stuff() // nothing, then the code in func1 will break. (And you'll still have an empty statement in func2 that just reads ;, which is perhaps even more superfluous.) On the other hand, if you have to actually define a do_stuff() function that returns -1, you may incur the cost of a function call for no good reason.

Is iter++-empty() a legal expression?

It's legal, but don't do it.

Asking yourself this question is reason enough to break it into two statements:

iter->empty();
iter++;

Why is it not allowed to declare empty expression body for methods?

[EDIT: This answer is not correct, do not use it - see comments.]

As you can see, expression body uses the lambda operator ("=>"). If you still want to write your empty void method as an expression body, you can use Expression.Empty() to show that Foo() is an empty (void) expression.

Methods that return void or Task should be implemented with expressions that don’t return anything, either. (https://learn.microsoft.com/en-us/archive/msdn-magazine/2014/october/csharp-the-new-and-improved-csharp-6-0)

The following code piece should work.

public void Foo() => Expression.Empty();

Also I agree with your last comment that it is a ReSharper bug.



Related Topics



Leave a reply



Submit