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
Opencv Unable to Set Up Svm Parameters
Static Constexpr Odr-Used or Not
At What Point Does Dereferencing the Null Pointer Become Undefined Behavior
Clean C++ Granular Friend Equivalent? (Answer: Attorney-Client Idiom)
At What Point Is It Worth Using a Database
How to Correctly Use Cv::Triangulatepoints()
Does New[] Call Default Constructor in C++
Finding Out the CPU Clock Frequency (Per Core, Per Processor)
What's the Motivation Behind Having Copy and Direct Initialization Behave Differently
Is There Any Way a C/C++ Program Can Crash Before Main()
How to Provider User with Autocomplete Suggestions for Given Boost::Spirit Grammar
Global Function Definition in Header File - How to Avoid Duplicated Symbol Linkage Error
Calling a Virtual Function from the Constructor
How to Convert from Int to Char*
In C++, What Does & Mean After a Function's Return Type
How to Tell Cmake to Use Clang on Windows