30 Dec, 2008, Zeno wrote in the 1st comment:
Votes: 0
In a nutshell, I have this:
sprintf( buf, "%s", get_char_world( ch, roster->name ) == NULL ? "offline" : "online" );


It's Smaug. See the problem? I need a !IS_NPC check there. Can C do 'and' logic with inline logic checks?
30 Dec, 2008, David Haley wrote in the 2nd comment:
Votes: 0
The result of a boolean test in C/C++ is the boolean value (0/1 or true/false depending on the exact language). This is unlike some other languages, where "true and x" results in "x" if "x" is true. I'm assuming that is what you mean by doing "'and' logic with inline logic checks".
30 Dec, 2008, tphegley wrote in the 3rd comment:
Votes: 0
Zeno said:
In a nutshell, I have this:
sprintf( buf, "%s", get_char_world( ch, roster->name ) == NULL ? "offline" : "online" );


It's Smaug. See the problem? I need a !IS_NPC check there. Can C do 'and' logic with inline logic checks?


Can you do something like:
sprintf( buf, "%s", IS_NPC(ch) ? "" : (get_char_world( ch, roster->name ) == NULL ? "offline" : "online" ) );



Not sure if this is doable or not.
30 Dec, 2008, David Haley wrote in the 4th comment:
Votes: 0
Yes, that would work (assuming it's the output he wants), but at this point, really, I think it would be nicer to use a temporary variable to avoid sticking so much logic into one line. If it has to stay one statement, at least break it up into several lines. E.g.

sprintf( buf, "%s",
IS_NPC(ch)
? ""
: (get_char_world( ch, roster->name ) == NULL
? "offline"
: "online" ) );

where how you format it is up to you, but something like the above is much more readable than just one line IMO.
30 Dec, 2008, tphegley wrote in the 5th comment:
Votes: 0
Do you say to use a temp variable to make it easier to read or would it be better performance wise (if just by a miniscule not even noticed amount) to use a temp variable?
30 Dec, 2008, David Haley wrote in the 6th comment:
Votes: 0
Oh, it's only for readability. You could call the temp variable "online_status", and then it's clear what's going on as you set it, and when you print it, it's extremely clear what string you're printing. I think it would have basically no effect performance-wise either way, since the compiler is (most likely) creating temporary "variables" for those intermediate expressions anyhow.
30 Dec, 2008, tphegley wrote in the 7th comment:
Votes: 0
DavidHaley said:
Oh, it's only for readability. You could call the temp variable "online_status", and then it's clear what's going on as you set it, and when you print it, it's extremely clear what string you're printing. I think it would have basically no effect performance-wise either way, since the compiler is (most likely) creating temporary "variables" for those intermediate expressions anyhow.


I find that as I learn more and more about C and C++, there are so many different ways to come to one thing. It's finding the most efficient, easiest ways (and easiest to read :cool:) that I guess will come in time. heh.
30 Dec, 2008, David Haley wrote in the 8th comment:
Votes: 0
Oh, certainly, writing code that is at once efficient and readable is an art that comes with practice (and with feedback, frankly, even if in the form of looking at your own code a few years later). Also, knowing when efficiency matters so much that you can sacrifice readability is something that comes with time. Anyhow, definitely an art. :wink:
30 Dec, 2008, elanthis wrote in the 9th comment:
Votes: 0
A good rule of thumb is to avoid over-thinking about efficiency. It is usually (though not always) a trade-off between highest efficiency and highest readability. In the grand scheme of things, your time is vastly more valuable than the CPU's time, so erring on the side of readable is far more important than erring on the side of performance.

Usually, the most important efficiency is simply in knowing which algorithm to use for a specific module, not in knowing how to eliminate a little overhead by using a temporary in the right place or whatever. if you ever find yourself wondering if using a temporary is going to affect performance, you're wasting your time for no measurable gain. :)
30 Dec, 2008, David Haley wrote in the 10th comment:
Votes: 0
For that matter, the compiler will usually be better than you (where you == almost any human) at figuring out how to optimize temporary use.
30 Dec, 2008, elanthis wrote in the 11th comment:
Votes: 0
The compiler won't really give you a choice. :) it'll just eliminate temporaries it sees no use for and add ones it thinks are valuable, all behind the scenes. It's going to do a lot of other things behind your back, too.

Modern performance tuning has far more to do with understanding the peculiarities of the hardware and isn't something that is easily understood or tweaked without using relatively advanced profiling tools. For example, an if statement or while loop can actually end up being slower than calculating the square root of a number, all because modern CPUs have very deep pipelines and pay a HUGE price for mis-predicted branches (the fact that CPUs now even _have_ branch prediction hardware is a clear sign of how complicated performance tuning really is).

You can also get huge performance boosts just by changing the total size of a struct/class (in some cases by making them larger, not smaller), which isn't really logical at all until you understand how the CPU and the cache system work at a very detailed level.

Best to just not worry about it at all, unless you're writing something that _really really really_ needs every last ounce of performance. (If your MUD falls into that category, you are doing something that can only be described as "horrifically freaking stupid." Many high-end 3D triple-A games don't even fall into that category anymore.)
30 Dec, 2008, Davion wrote in the 12th comment:
Votes: 0
#include <stdio.h>

int main()
{ unsigned char yes = 1;
unsigned char no = 0;

printf("%s\n", (yes && !no) ? "Online" : "Offline");
no = 1;

printf("%s\n", (yes && !no) ? "Online" : "Offline");

return 1;
}


Seems to work for me. Try

sprintf( buf, "%s", (!IS_NPC(ch) && get_char_world( ch, roster->name ) == NULL) ? "offline" : "online" );
31 Dec, 2008, Zeno wrote in the 13th comment:
Votes: 0
Yes Davion has what I was asking.

Although it's pointless to check !IS_NPC on ch.

The problem was that it would return true for players with names like mobs (Mai->mailman) and would say they are online.
31 Dec, 2008, David Haley wrote in the 14th comment:
Votes: 0
I don't understand what you were asking then. Were you only asking if it's possible to use && in boolean expressions?
31 Dec, 2008, Zeno wrote in the 15th comment:
Votes: 0
Using && in the args of that sprintf, essentially like Davion did. Had no idea how to word it. :P
31 Dec, 2008, David Haley wrote in the 16th comment:
Votes: 0
Ah, I see. Well, any time you ever have an expression, you can use whatever operators you wish. C makes no distinction between expressions that are arguments to a function, a conditional, or a tri-part conditional like the one you had. That's why I thought you were talking about something like what other languages let you do (which is pretty handy, really).
31 Dec, 2008, Tyche wrote in the 17th comment:
Votes: 0
There is a compiler dependent limit on how many expressions you can nest in function calls, but it's probably well beyond readability (unless you are a Lisp programmer).
31 Dec, 2008, quixadhal wrote in the 18th comment:
Votes: 0
Bonus question, to flush out the LISP programmers…. What would this evaluate to if there were no syntax errors?

(cadadr ((((1 2)(3 4))((5 6)(7 8)))(((9 10)(11 12))((13 14)(15 16)))))

Tyche said:
There is a compiler dependent limit on how many expressions you can nest in function calls, but it's probably well beyond readability (unless you are a Lisp programmer).
31 Dec, 2008, Tyche wrote in the 19th comment:
Votes: 0
11?
31 Dec, 2008, David Haley wrote in the 20th comment:
Votes: 0
cadadr x = car of cdr of car of cdr of x

In this case, I believe that is ((13 14) (15 16)), since the cdr of x is pairs 9…16, the car of which is unnesting parens, the cdr of which is pairs 13..16, and finally the car unnests parens again.

Of course, this isn't so much a test of ability to program in Lisp as it is to break apart the parentheses :wink: I can program in Lisp and that expression is still incomprehensible until I break it up with indents etc.
0.0/38