How to prevent unwanted variable assignment inside condition statement? - debugging

Missing equal sign inside assignment (typing = instead of ==) make unwanted assignment inside a condition statement.
For example, consider the scenario below (this example is in C, but the question is valid also for interpreted code).
CASE A:
int g=1;
if ( g == 3 )
{
printf("g is 3");
}
else
{
printf("g is not 3");
}
//this return: "g is not 3"
CASE B: (typo: missing = inside condition)
int g=1;
if ( g = 3 )
{
printf("g is 3");
}
else
{
printf("g is not 3");
}
//this return: "g is 3" because of the assignment
Both the cases are formally correct, so the code will work but not as we want; and may be hard to debug.
How to prevent this situation? There is a solution that cover the interpreted code (for example javascript), apart static analyzers?

The thing is, using an assignment inside a condition body for if, while, or for is perfectly valid C and is very often used intentionally. For example, I often find myself using the following skeleton code to create a window when writing a Win32 API GUI:
if((hWnd = CreateWindowExW(...)) == NULL)
{
MessageBoxW(NULL, L"Window creation failed", L"Error", MB_OK | MB_ICONSTOP);
return GetLastError();
}
If the test is solely for equality and you want to avoid using the = operator accidentally, one thing you can do is get into the habit of putting the r-value on the left side of the operator, so that if you accidentally use =, it will produce a compilation error:
char *p = malloc(100000);
if(NULL == p)
{
// handle null pointer
}
Obviously, this only works if at least one side of the comparison is an r-value or a const variable.

Related

Referencing / dereferencing a vector element in a for loop

In the code below, I want to retain number_list, after iterating over it, since the .into_iter() that for uses by default will consume. Thus, I am assuming that n: &i32 and I can get the value of n by dereferencing.
fn main() {
let number_list = vec![24, 34, 100, 65];
let mut largest = number_list[0];
for n in &number_list {
if *n > largest {
largest = *n;
}
}
println!("{}", largest);
}
It was revealed to me that instead of this, we can use &n as a 'pattern':
fn main() {
let number_list = vec![24, 34, 100, 65];
let mut largest = number_list[0];
for &n in &number_list {
if n > largest {
largest = n;
}
}
println!("{}", largest);
number_list;
}
My confusion (and bear in mind I haven't covered patterns) is that I would expect that since n: &i32, then &n: &&i32 rather than it resolving to the value (if a double ref is even possible). Why does this happen, and does the meaning of & differ depending on context?
It can help to think of a reference as a kind of container. For comparison, consider Option, where we can "unwrap" the value using pattern-matching, for example in an if let statement:
let n = 100;
let opt = Some(n);
if let Some(p) = opt {
// do something with p
}
We call Some and None constructors for Option, because they each produce a value of type Option. In the same way, you can think of & as a constructor for a reference. And the syntax is symmetric:
let n = 100;
let reference = &n;
if let &p = reference {
// do something with p
}
You can use this feature in any place where you are binding a value to a variable, which happens all over the place. For example:
if let, as above
match expressions:
match opt {
Some(1) => { ... },
Some(p) => { ... },
None => { ... },
}
match reference {
&1 => { ... },
&p => { ... },
}
In function arguments:
fn foo(&p: &i32) { ... }
Loops:
for &p in iter_of_i32_refs {
...
}
And probably more.
Note that the last two won't work for Option because they would panic if a None was found instead of a Some, but that can't happen with references because they only have one constructor, &.
does the meaning of & differ depending on context?
Hopefully, if you can interpret & as a constructor instead of an operator, then you'll see that its meaning doesn't change. It's a pretty cool feature of Rust that you can use constructors on the right hand side of an expression for creating values and on the left hand side for taking them apart (destructuring).
As apart from other languages (C++), &n in this case isn't a reference, but pattern matching, which means that this is expecting a reference.
The opposite of this would be ref n which would give you &&i32 as a type.
This is also the case for closures, e.g.
(0..).filter(|&idx| idx < 10)...
Please note, that this will move the variable, e.g. you cannot do this with types, that don't implement the Copy trait.
My confusion (and bear in mind I haven't covered patterns) is that I would expect that since n: &i32, then &n: &&i32 rather than it resolving to the value (if a double ref is even possible). Why does this happen, and does the meaning of & differ depending on context?
When you do pattern matching (for example when you write for &n in &number_list), you're not saying that n is an &i32, instead you are saying that &n (the pattern) is an &i32 (the expression) from which the compiler infers that n is an i32.
Similar things happen for all kinds of pattern, for example when pattern-matching in if let Some (x) = Some (42) { /* … */ } we are saying that Some (x) is Some (42), therefore x is 42.

std::vector erase issue with MSVC 2010

ALL,
I have a class defined that just holds the data (different types of data). I also have std::vector that holds a pointers to objects of this class.
Something like this:
class Foo
{
};
class Bar
{
private:
std::vector<Foo *> m_fooVector;
};
At one point of time in my program I want to remove an element from this vector. And so I write following:
for (std::vector<Foo *>::iterator it = m_fooVector.begin(); it <= m_fooVector.end(); )
{
if( checking it condition is true )
{
delete (*it);
(*it) = NULL;
m_fooVector.erase( it );
}
}
The problem is that the erase operation fails. When I open the debugger I still see this element inside the vector and when the program finishes it crashes because the element is half way here.
In another function I am trying to remove the simple std::wstring from the vector and everything works fine - string is removed and the size of the vector decreased.
What could be the problem for such behavior? I could of course try to check the erase function in MSVC standard library, but I don't even know where to start.
TIA!!!
Your loop is incorrect:
for (std::vector<Foo *>::iterator it = m_fooVector.begin(); it != m_fooVector.end(); )
{
if (/*checking it condition is true*/)
{
delete *it;
// *it = NULL; // Not needed
it = m_fooVector.erase(it);
} else {
++it;
}
}
Traditional way is erase-remove idiom, but as you have to call delete first (smart pointer would avoid this issue), you might use std::partition instead of std::remove:
auto it = std::partition(m_fooVector.begin(), m_fooVector.end(), ShouldBeKeptFunc);
for (std::vector<Foo *>::iterator it = m_fooVector.begin(); it != m_fooVector.end(); ++it) {
delete *it;
}
m_fooVector.erase(it, m_fooVector.end());

C++11 Magic to test and assign from pointer if not nullptr

Okay, I believe in defensive programming. I assume that if I get a pointer it might be null (especially when using GSOAP). Therefore before I try to use the value of the pointer, I always check to make sure the pointer is not null.
In my current code, this is leading to a lot of nearly identical statements.
if (res->A) {
item.out_trace->a = *res->A;
}
if (res->B) {
item.out_trace->b = *res->B;
}
if (res->C) {
item.out_trace->b = *res->C;
}
I realize that I could always go and define a macro for this, but I am wondering if there is a neat C++11 trick to do that. I would love something like the C# ??
// Set y to the value of x if x is NOT null; otherwise,
// if x = null, set y to -1.
int y = x ?? -1;
Thanks.
Perhaps a template like this would meet your need:
template<typename T>
T safe_get( T const *ptr, T defval = T{} ) {
return ptr ? *ptr : std::move(defval);
}
It could be used like this:
item.out_trace->a = safe_get( rez->A );
Ideally it would be inlined and effectively zero-overhead (other than the inherent overhead of doing the safety check and having a branch, of course).

Is there a tool that computes what happens in a method based on the values of the args passed in?

I'm working on a legacy app that is not just spaghetti, but turns to egg shells when broken (Humpty Dumpty syndrome), where figuring out what is going on as the code meanders around like a drunken sailor in Old Manila is like trying to find a poodle in a smokestack.
As an example, here is a method that I must grok; this is just the first part of it:
private void InitializeBackgroundThread( LoginStatuses loginStatus, string DialogCap )
{
try
{
double pause = 1;
int wait = 250;
ProgressChangedFlag = false;
ProgressChangedIndex = 0;
pc = new PendingCommands( pause, wait );
PendingCommands.ProcessCommands = true;
if (!((loginStatus == LoginStatuses.LoginVendors) || (loginStatus == LoginStatuses.LoginInventory)))
PendingCommands.Processing = false;
PendingCommands.Timeout = false;
Util.StopCancelRequested = false;
if( timeOut != "" )
pc.timeOut = timeOut;
if (!((loginStatus == LoginStatuses.LoginVendors) || (loginStatus == LoginStatuses.LoginInventory)))
{
InitializeBackgroundThread_CCRLoginTerminate (true);
InitializeBackgroundThread_CCRTimerExceeded (true);
InitializeBackgroundThread_CCROnline (true);
}
if (loginStatus == LoginStatuses.LoginVendors)
{
InitializeBackgroundThread_CCRCommandConfirmedGetsites (false);
InitializeBackgroundThread_CCRCommandConfirmed (false);
InitializeBackgroundThread_CCRCommandConfirmedSitesetup (true);
}
else if (loginStatus == LoginStatuses.LoginSitesData)
{
InitializeBackgroundThread_CCRCommandConfirmed (false);
InitializeBackgroundThread_CCRCommandConfirmedSitesetup (false);
InitializeBackgroundThread_CCRCommandConfirmedGetsites (true);
}
else
{
InitializeBackgroundThread_CCRCommandConfirmedSitesetup (false);
InitializeBackgroundThread_CCRCommandConfirmedGetsites (false);
InitializeBackgroundThread_CCRCommandConfirmed (true);
}
InitializeBackgroundThread_CCRProgress (true);
InitializeBackgroundThread_CCRProgressChanged (true);
InitializeBackgroundThread_CCRProgressComm (true);
Now I can "deskcheck" it by going through it with a notepad, asking myself, "Okay, what will happen - which variables will be assigned which values, and which methods will be called - if loginStatus is "AllQuiet"? What if loginStatus is "SNAFU"? Etc. etc. ad nauseum.
Wouldn't it be great if a tool could eat this spaghetti right up and spit out a report such as:
*With a loginStatus of "AllQuiet"
PendingCommands.Processing is set to true.
InitializeBackgroundThread_CCRProgressChanged is called.
...
With a loginStatus of "SNAFU"
(etc.)*
This would be a "killer" debugging/sanity check tool. I know there are code coverage tools, but are there any that are this sophisticated?
This isn't code coverage, which simply tracks what code gets executed if you run a specific test.
What you want is something like a cross between program slicing ("show me everything downstream/upstream from some code point" aka 'a slice' http://en.wikipedia.org/wiki/Program_slicing),
and partial evaluation ("show me what this code looks like if I assume some value is a specific constant" http://en.wikipedia.org/wiki/Partial_evaluation). And you want it to display the result superimposed on top of your actual code (e.g. boldface the selected part) to see your focus.
Yes, that would be wickedly nice tool.
No, I don't know of any. There are program slicers for C and C++ (See http://www.grammatech.com/research/technologies/codesurfer). I don't think they have the partial evaluation part, but I think they do have some other options to minimize the size the slice being inspected.

Redundant code constructs

The most egregiously redundant code construct I often see involves using the code sequence
if (condition)
return true;
else
return false;
instead of simply writing
return (condition);
I've seen this beginner error in all sorts of languages: from Pascal and C to PHP and Java. What other such constructs would you flag in a code review?
if (foo == true)
{
do stuff
}
I keep telling the developer that does that that it should be
if ((foo == true) == true)
{
do stuff
}
but he hasn't gotten the hint yet.
if (condition == true)
{
...
}
instead of
if (condition)
{
...
}
Edit:
or even worse and turning around the conditional test:
if (condition == false)
{
...
}
which is easily read as
if (condition) then ...
Using comments instead of source control:
-Commenting out or renaming functions instead of deleting them and trusting that source control can get them back for you if needed.
-Adding comments like "RWF Change" instead of just making the change and letting source control assign the blame.
Somewhere I’ve spotted this thing, which I find to be the pinnacle of boolean redundancy:
return (test == 1)? ((test == 0) ? 0 : 1) : ((test == 0) ? 0 : 1);
:-)
Redundant code is not in itself an error. But if you're really trying to save every character
return (condition);
is redundant too. You can write:
return condition;
Declaring separately from assignment in languages other than C:
int foo;
foo = GetFoo();
Returning uselessly at the end:
// stuff
return;
}
I once had a guy who repeatedly did this:
bool a;
bool b;
...
if (a == true)
b = true;
else
b = false;
void myfunction() {
if(condition) {
// Do some stuff
if(othercond) {
// Do more stuff
}
}
}
instead of
void myfunction() {
if(!condition)
return;
// Do some stuff
if(!othercond)
return;
// Do more stuff
}
Using .tostring on a string
Putting an exit statement as first statement in a function to disable the execution of that function, instead of one of the following options:
Completely removing the function
Commenting the function body
Keeping the function but deleting all the code
Using the exit as first statement makes it very hard to spot, you can easily read over it.
Fear of null (this also can lead to serious problems):
if (name != null)
person.Name = name;
Redundant if's (not using else):
if (!IsPostback)
{
// do something
}
if (IsPostback)
{
// do something else
}
Redundant checks (Split never returns null):
string[] words = sentence.Split(' ');
if (words != null)
More on checks (the second check is redundant if you are going to loop)
if (myArray != null && myArray.Length > 0)
foreach (string s in myArray)
And my favorite for ASP.NET: Scattered DataBinds all over the code in order to make the page render.
Copy paste redundancy:
if (x > 0)
{
// a lot of code to calculate z
y = x + z;
}
else
{
// a lot of code to calculate z
y = x - z;
}
instead of
if (x > 0)
y = x + CalcZ(x);
else
y = x - CalcZ(x);
or even better (or more obfuscated)
y = x + (x > 0 ? 1 : -1) * CalcZ(x)
Allocating elements on the heap instead of the stack.
{
char buff = malloc(1024);
/* ... */
free(buff);
}
instead of
{
char buff[1024];
/* ... */
}
or
{
struct foo *x = (struct foo *)malloc(sizeof(struct foo));
x->a = ...;
bar(x);
free(x);
}
instead of
{
struct foo x;
x.a = ...;
bar(&x);
}
The most common redundant code construct I see is code that is never called from anywhere in the program.
The other is design patterns used where there is no point in using them. For example, writing "new BobFactory().createBob()" everywhere, instead of just writing "new Bob()".
Deleting unused and unnecessary code can massively improve the quality of the system and the team's ability to maintain it. The benefits are often startling to teams who have never considered deleting unnecessary code from their system. I once performed a code review by sitting with a team and deleting over half the code in their project without changing the functionality of their system. I thought they'd be offended but they frequently asked me back for design advice and feedback after that.
I often run into the following:
function foo() {
if ( something ) {
return;
} else {
do_something();
}
}
But it doesn't help telling them that the else is useless here. It has to be either
function foo() {
if ( something ) {
return;
}
do_something();
}
or - depending on the length of checks that are done before do_something():
function foo() {
if ( !something ) {
do_something();
}
}
From nightmarish code reviews.....
char s[100];
followed by
memset(s,0,100);
followed by
s[strlen(s)] = 0;
with lots of nasty
if (strcmp(s, "1") == 0)
littered about the code.
Using an array when you want set behavior. You need to check everything to make sure its not in the array before you insert it, which makes your code longer and slower.
Redundant .ToString() invocations:
const int foo = 5;
Console.WriteLine("Number of Items: " + foo.ToString());
Unnecessary string formatting:
const int foo = 5;
Console.WriteLine("Number of Items: {0}", foo);

Resources