What does the following code do in C/C++?
if (blah(), 5) {
//do something
}
Comma operator is applied and the value 5 is used to determine the conditional's true/false.
It will execute blah() and get something back (presumably), then the comma operator is employed and 5 will be the only thing that is used to determine the true/false value for the expression.
Note that the , operator could be overloaded for the return type of the blah() function (which wasn't specified), making the result non-obvious.
If the comma operator is not overloaded, the code is similar to this:
blah();
if (5) {
// do something
}
If the comma operator is overloaded, the result will be based on that function.
#include <iostream>
#include <string>
using namespace std;
string blah()
{
return "blah";
}
bool operator,(const string& key, const int& val) {
return false;
}
int main (int argc, char * const argv[]) {
if (blah(), 5) {
cout << "if block";
} else {
cout << "else block";
}
return 0;
}
(edited to show comma operator overloading scenario. thanks to David Pierre for commenting on this)
I know one thing that this kind of code should do: it should get the coder fired. I would be quite a bit afraid to work next to someone who writes like this.
In the pathological case, it depends on what the comma operator does...
class PlaceHolder
{
};
PlaceHolder Blah() { return PlaceHolder(); }
bool operator,(PlaceHolder, int) { return false; }
if (Blah(), 5)
{
cout << "This will never run.";
}
I would say that depends on blah().
On a more broad answer. The comma operator (non overloaded) resolves as in, execute the first part and return the second part.
So if you have (foo(),bar()) Both functions will be executed, but the value of the expression evaluates to bar() (and the type of the expression as well).
While I won't say there are fair usages for that, is usually considered a bit hard to read code. Mainly because not many languages shares such constructs. So As a personal rule of thumb I avoid it unless I am adding code to a preexistent expression and don't want to change completely its format.
Example: I have a Macro (not discussing if you should use macros or not, sometimes its not even you that wrote it)
FIND_SOMETHING(X) (x>2) ? find_fruits(x) : find_houses(x)
And I usually use it in assignments like my_possession = FIND_SOMETHING(34);
Now I want to add log to it for debuggin purposes but I cannot change the find functions,. I could do :
FIND_SOMETHING(X) (x>2)? (LOG("looking for fruits"),find_fruits(x)):(LOG("looking for houses"),find_houses(x))
I use sometimes constructs like this for debugging purposes. When I force the if close to be true regardless of the return value of blah.
It's obvious that it should never appear in production code.
The following was written assuming it is C code, either in a C file or within a C block of a C++ file:
It is a pointless if. It will call blah(), however the result of blah() is not considered by if at all. The only thing being considered is 5, thus the if will always evaluate to true. IOW you could write this code as
blah();
// do something
without any if at all.
Related
I have the following code:
Foo a;
if (some_fairly_long_condition) {
a = complicated_expression_to_make_foo_1();
} else {
a = complicated_expression_to_make_foo_2();
}
I have two issues with this:
a is a const and should be declared so
the "empty" constructor, Foo() is called for no reason (maybe this is optimised away?)
One way to fix it is by using the ternary operator:
const Foo a = some_fairly_long_condition?
complicated_expression_to_make_foo_1():
complicated_expression_to_make_foo_2();
Is this good practice? How do you go about it?
To answer the second part of your question:
I usually put the initialization code into a lambda:
const Foo a = [&]()->Foo{
if (some_fairly_long_condition) {
return complicated_expression_to_make_foo_1();
} else {
return complicated_expression_to_make_foo_2();
}
}();
In most cases you should even be able to omit the trailing return type, so you can write
const Foo a = [&](){ ...
As far as the first part is concerned:
I'd say that greatly depends on how complex your initialization code is. If all three parts are really complicated expressions (and not just a function call each) then the solution with the ternary operator becomes an unreadable mess, while the lambda method (or a separate named function for that matter) allows you to break up those parts into the respective sub expressions.
If the problem is to avoid ternaty operator and your goal is to define the constant a, this code is an option:
Foo aux;
if (some_fairly_long_condition) {
aux = complicated_expression_to_make_foo_1();
} else {
aux = complicated_expression_to_make_foo_2();
}
const Foo a(aux);
It is a good solution, without any new feature ---as lambdas--- and including the code inline, as you want.
I have code that does something like this:
//datareader.cpp
if (populateFoo(dataReader, foo))
else {
// Do other things with the reader.
}
//foo.cpp
bool populateFoo(const DataReader &dataReader, Foo &foo)
{
if (dataReader.name() == "bar") {
foo.bar() = dataReader.value();
return true;
} // More similar checks.
return false;
}
I feel like it's misleading to have an if statement with conditions that have side-effects. However, I can't move the body of the populateFoo function into datareader.cpp. Is there a good way to restructure this code so we get rid of this misleading if statement, without duplicating the body of populateFoo()?
Do you have a strong hatred of local variables? If not:
bool populated = populateFoo(dataReader, foo);
if (populated)
{
// Do things
}
else
{
// Do other things
}
The compiler will almost certainly emit exactly the same code, so performance shouldn't be an issue. It's a readability/style choice, ultimately.
The obvious solution seems like storing the result of populateFoo and using it for determining whether populateFoo was successful:
bool fooPopulated = populateFoo(dataReader, Foo);
if (!fooPopulated)
//Do other things with reader.
However, I don't find the original difficult to understand, and it's a fairly well-established practice to both modify values and test the success of the modification in the same line. However, I would change it to:
if (!populateFoo(dataReader, Foo)
//Do other things with reader.
How about:
if (!populateFoo(dataReader, foo)) {
// Do other things with the reader.
}
Edit: The title of the question suggests it is the fact the if statement is empty that bothers you but the body seems more that it is the side effect that is the concern. I think it's fine in C++ to have conditions in if statements that have side effects but this won't solve your issue if you want to avoid that.
Having conditions with side-effects is quite common - think about calling a C API and checking its return code for errors.
Usually, as long as it's not buried in a complicated expression where it may be missed by the casual bystander, I don't bother to do particular refactorings, but, in case you wanted to make it extra clear (or document what the return value is, which is particularly useful in case of booleans) just assign it to a variable before the branch - or even just a few comments may help.
You could split the populateFoo function into two, a const check function (shouldPopulateFoo) that checks the condition, and another non-const function that performs the actual modifications (populateFoo):
//datareader.cpp
if (shouldPopulateFoo(dataReader)) {
populateFoo(dataReader, foo);
}
else {
// Do other things with the reader.
}
//foo.cpp
bool shouldPopulateFoo(const DataReader &dataReader) /* const */
{
return (dataReader.name() == "bar");
}
void populateFoo(const DataReader &dataReader, Foo &foo) /* non-const */
{
assert(shouldPopulateFoo(dataReader));
foo.bar = dataReader.value();
}
Note that when using these functions as class methods, you could declare the check function const.
How about:
if (populateFoo(dataReader, foo) == false) {
// Do other things with the reader.
}
It is very readable, I often see code where the returned value from function is a signal to the caller for branching in the caller. The else block with empty if block bothers me more then the side effects inside the if (). There is a sense of reverse logic, which is alway less readable.
What does the following code do in C/C++?
if (blah(), 5) {
//do something
}
Comma operator is applied and the value 5 is used to determine the conditional's true/false.
It will execute blah() and get something back (presumably), then the comma operator is employed and 5 will be the only thing that is used to determine the true/false value for the expression.
Note that the , operator could be overloaded for the return type of the blah() function (which wasn't specified), making the result non-obvious.
If the comma operator is not overloaded, the code is similar to this:
blah();
if (5) {
// do something
}
If the comma operator is overloaded, the result will be based on that function.
#include <iostream>
#include <string>
using namespace std;
string blah()
{
return "blah";
}
bool operator,(const string& key, const int& val) {
return false;
}
int main (int argc, char * const argv[]) {
if (blah(), 5) {
cout << "if block";
} else {
cout << "else block";
}
return 0;
}
(edited to show comma operator overloading scenario. thanks to David Pierre for commenting on this)
I know one thing that this kind of code should do: it should get the coder fired. I would be quite a bit afraid to work next to someone who writes like this.
In the pathological case, it depends on what the comma operator does...
class PlaceHolder
{
};
PlaceHolder Blah() { return PlaceHolder(); }
bool operator,(PlaceHolder, int) { return false; }
if (Blah(), 5)
{
cout << "This will never run.";
}
I would say that depends on blah().
On a more broad answer. The comma operator (non overloaded) resolves as in, execute the first part and return the second part.
So if you have (foo(),bar()) Both functions will be executed, but the value of the expression evaluates to bar() (and the type of the expression as well).
While I won't say there are fair usages for that, is usually considered a bit hard to read code. Mainly because not many languages shares such constructs. So As a personal rule of thumb I avoid it unless I am adding code to a preexistent expression and don't want to change completely its format.
Example: I have a Macro (not discussing if you should use macros or not, sometimes its not even you that wrote it)
FIND_SOMETHING(X) (x>2) ? find_fruits(x) : find_houses(x)
And I usually use it in assignments like my_possession = FIND_SOMETHING(34);
Now I want to add log to it for debuggin purposes but I cannot change the find functions,. I could do :
FIND_SOMETHING(X) (x>2)? (LOG("looking for fruits"),find_fruits(x)):(LOG("looking for houses"),find_houses(x))
I use sometimes constructs like this for debugging purposes. When I force the if close to be true regardless of the return value of blah.
It's obvious that it should never appear in production code.
The following was written assuming it is C code, either in a C file or within a C block of a C++ file:
It is a pointless if. It will call blah(), however the result of blah() is not considered by if at all. The only thing being considered is 5, thus the if will always evaluate to true. IOW you could write this code as
blah();
// do something
without any if at all.
When refactoring some code, I often encounter this :
bool highLevelFunc foo()
{
// ...
bool result = LesserLevelFunc();
if (!result) return false;
// ... Keep having fun if we didn't return
}
Is there any way to make this a little more sexy and less verbose ? Without any overhead or pitfall of course.
I can think of a macro
#define FORWARD_IF_FALSE(r) if (!r) return r;
bool highLevelFunc foo()
{
// ...
FORWARD_IF_FALSE(LesserLevelFunc());
// ...
}
Anything better, i.e without preprocessor macro?
To me, "readable" code is sexy. I find the original code more readable than your proposal, since the original uses standard C++ syntax and the latter uses a macro which I'd have to go and look up.
If you want to be more explicit, you could say if (result == false) (or better yet, if (false == result) to prevent a possible assignment-as-comparison bug) but understanding the ! operator is a fairly reasonable expectation in my opinion.
That said, there is no reason to assign the return value to a temporary variable; you could just as easily say:
if (!LesserLevelFunc()) return false;
This is quite readable to me.
EDIT: You could also consider using exceptions instead of return values to communicate failure. If LesserLevelFunc() threw an exception, you would not need to write any special code in highLevelFunc() to check for success. The exception would propagate up through the caller to the nearest matching catch block.
Because you might be continuing if LesserLevelFunc returns true, I suggest keeping it pretty close to how it is now:
if (!LesserLevelFunc())
return false;
First of all introducing the macro you are making the code unsafe. Moreover your macro is invalid.
The expression after the negation operator shall be enclosed in parentheses.
#define FORWARD_IF_FALSE(r) if (!( r ) ) return r;
Secondly the macro calls r twice. Sometimes two calls of a function is not equivalent to one call of the same function. For example the function can have some side effects or internal flags that are switched on/off in each call of the function.
So I would keep the code as is without introducing the macro because the macro does not equivalent to the symantic of the original code.
I am looking for a portable way to implement lazy evaluation in C++ for logging class.
Let's say that I have a simple logging function like
void syslog(int priority, const char *format, ...);
then in syslog() function we can do:
if (priority < current_priority)
return;
so we never actually call the formatting function (sprintf).
On the other hand, if we use logging stream like
log << LOG_NOTICE << "test " << 123;
all the formating is always executed, which may take a lot of time.
Is there any possibility to actually use all the goodies of ostream (like custom << operator for classes, type safety, elegant syntax...) in a way that the formating is executed AFTER the logging level is checked ?
This looks like something that could be handled with expression templates. Beware, however, that expression templates can be decidedly non-trivial to implement.
The general idea of how they work is that the operators just build up a temporary object, and you pass that temporary object to your logging object. The logging object would look at the logging level and decide whether to carry out the actions embodied in the temporary object, or just discard it.
What I've done in our apps is to return a boost::iostreams::null_stream in the case where the logging level filters that statement. That works reasonably well, but will still call all << operators.
If the log level is set at compile time, you could switch to an object with a null << operator.
Otherwise, it's expression templates as Jerry said.
The easiest and most straight-forward way is to simply move the check outside of the formatting:
MyLogger log; // Probably a global variable or similar.
if (log.notice())
log << "notified!\n" << some_function("which takes forever to compute"
" and which it is impossible to elide if the check is inside log's"
" op<< or similar");
if (log.warn()) {
log << "warned!\n";
T x;
longer_code_computing(value_for, x); // easily separate out this logic
log << x;
}
If you really wanted to shorten the common case, you could use a macro:
#define LOG_NOTICE(logger) if (logger.notice()) logger <<
LOG_NOTICE(log) << "foo\n";
// instead of:
if (log.notice()) log << "foo\n";
But the savings is marginal.
One possible MyLogger:
struct MyLogger {
int priority_threshold;
bool notice() const { return notice_priority < current_priority; }
bool warn() const { return warn_priority < current_priority; }
bool etc() const { return etc_priority < current_priority; }
template<class T>
MyLogger& operator<<(T const &x) {
do_something_with(x);
return *this;
}
};
The problem here is mixing iostream-style operator overloading with a printf-like logging function – specifically translating manipulators and formatting flags/fields from iostreams into a format string. You could write to a stringstream and then chunk that to your syslog function, or try something fancier. The above MyLogger works easiest if it also contains an ostream reference to which it can forward, but you'll need a few more op<< overloads for iomanips (e.g. endl) if you do that.
For mine I made a debug_ostream class which has templated << operators. These operators check the debug level before calling the real operator.
You will need to define non-template overrides for const char* and std::ostream& (*x)(std::ostream&) because otherwise those don't work. I'm not sure why.
With inlining and high enough optimization levels the compiler will turn the whole output line into a single check of the debug level instead of one per output item.
I should add to this that this doesn't solve the original problem. For example if part of the debug line is to call an expensive function to get a value for output, that function will still be called. My solution only skips the formatting overhead.