Time to time I see some common mistakes or even make some my self. I figure I would post some of these, with hopes that people will learn from my and others mistakes.

1) Why you no work?

int sum = 0;
for(int i = 1; i < MAX; ++i);
{
  sum += i;
}

2)Why you work so well?

char * arguments[argCount] //argCount defined somewhere else
for(int i = 0; i < argCount; ++i){
 char *arg = new char[256];
 initialize(arg,256); //assume 
 arguments[i] = arg;
 delete arg;
 arg = NULL;
}

3) I use C++ like I use math!

int input = 0;
cin >> input;

char letterGrade;
if(50 <= input <= 60) letterGrade = 'F'; //Fail
else letterGrade = 'P'; //Pass

4)Why you garbage one time and work other?

int x;
get(x);
doStuff(x);
//....
void get(int& x){
 if(! (cin >> x) ){ resetStream(cin); } //assume resetStream resets cin to valid
}

5)Why you garbage one time and work other?

int input;
char letterGrade;
cin >> input;
if( 0 < input && input < 70) letterGrade = 'F';
else if(70 < input && input < 100) letterGrade = 'P';

6)Why you not print all?

void print(int *arr){
 for(int i = 0; i < sizeof(arr)/sizeof(*arr); ++i){ cout << arr[i] << endl; }
}

7) Why you wrong value?

//x,y are passed coordinates and buttonID is the id of which button is clicked
void mousePressed(int x, int y, char buttonID){
 if(buttonID == LEFT_BUTTON){
   int x = x/WINDOW + OFFSET;
   int y = y/WINDOW + OFFSET;
   player.move(x,y);
 }
}

8) Why I so skinny?

int myWeight = 50;
int yourWeight = 100;
cout << "I am " << myWeight/yourWeight << " times skinner than you? ";

These are just some common mistakes I have witness people make, some I made before. I left the solution as an exercise to the reader( ask/post if you want answer ). Some of these are straight forward, others aren't as much. Some have more than one bugs.

If you have some common mistakes people usually make, post it here to contribute. Thanks.

Regards, D.Chhetri

EDIT: Just to clarify, the reason why I'm not posting the answers right now is to help you learn. Reading it might make you aware of it, but thinking will help you learn. After you have figured it out, post here or msg me, then you will get evaluated. Also after some time, I will post all answers.

Edited 5 Years Ago by firstPerson: n/a

poor me.. i don't know the problem on 4,5,6...

4) Enter in "bad" values like ""error" (anything that's not a legal int) and see if the function recovers correctly so that the code works when you finally enter GOOD data.

5) Can you ever enter a valid score and not get a grade assigned or the WRONG grade assigned.

6) Create an array of 10 integers in main, initialize them, then see if "print" displays them correctly.

I'll add one. How come I never seem to guess right?

float secret_number = 999999999;
    int guess;
    cout << "Enter guess : ";
    cin >> guess;
    if(guess == secret_number)
    {
        cout << "You guessed right.\n";
    }
Comments
Nice you almost had me fooled for a second.

I solved most of the originals right :) I did not only solve 1 (I think).

float secret_number = 999999999;
int guess;
cout << "Enter guess : ";
cin >> guess;
if(guess == secret_number)
{
    cout << "You guessed right.\n";
}

Int cannot hold that many values?

Edited 3 Years Ago by mike_2000_17: Fixed formatting

float secret_number = 999999999;
    int guess;
    cout << "Enter guess : ";
    cin >> guess;
    if(guess == 999999999)
    {
        cout << "You guessed right.\n";
    }

Hint... This works.

I solved most of the originals right :) I did not only solve 1 (I think).
Int cannot hold that many values?

Think more of promotion and representation.

compare in different type? so need to typecast or be same type?

Edited 5 Years Ago by murnesty: n/a

compare in different type? so need to typecast or be same type?

If a float cannot hold 999999999 (and it indeed cannot), the battle is already lost. Typecasting won't work. Float has 4 bytes, as does int. Since float can represent numbers that int cannot, it stands to reason that, being the same size, int will be able to represent numbers that float cannot. I simply picked one of them(999999999). The first time I wrote the program, I picked a number on accident that actually worked, so if you put the right number in there, the program will work. Replace "float" with "double" and the program works because doubles can represent any number that an int can represent.


Here's another one, slightly harder. Calculators are allowed. What should you guess? And do you care what kind of computer this program is running on? If so, why? And do you need any more information or is this snippet sufficient to guess correctly?

int secret_number;
    char* aString = "012";

    strcpy((char*) &secret_number, aString);

    int guess;

    cout << "Enter guess : ";
    cin >> guess;

    if(guess == secret_number)
    {
        cout << "You guessed right.\n";
    }

Edited 5 Years Ago by VernonDozier: n/a

And do you need any more information or is this snippet sufficient to guess correctly?

The correct answer is "send the code back to the author with a bug report". Copying bytes into an int punned as char* is only safe when the bytes being copied were acquired from another int. Otherwise you risk creating a trap representation.

>> strcpy((char*) &secret_number, aString);
That should fail on most processors. Why? because you can't just simply copy the contents of a string to an integer. The contents of aString have to be converted to int using something like strtol()

[edit]I think this is what Narue was talking about too :)

Edited 5 Years Ago by Ancient Dragon: n/a

Here's another one:

#include <iostream>

struct B
{
    virtual void print(const char * msg = "wtf? -.-")
    {
        std::cout << msg << std::endl;
    }

    virtual ~B() {}
};

struct D : B
{
    void print(const char * msg = "Hello, World!")
    {
        std::cout << msg << std::endl;
    }
};

int main()
{
    B * pb = new D;

    pb->print();

    delete pb;

    return 0;
}
Comments
cool
nice 1

Here's another one:

#include <iostream>

struct B
{
    virtual void print(const char * msg = "wtf? -.-")
    {
        std::cout << msg << std::endl;
    }

    virtual ~B() {}
};

struct D : B
{
    void print(const char * msg = "Hello, World!")
    {
        std::cout << msg << std::endl;
    }
};

int main()
{
    B * pb = new D;

    pb->print();

    delete pb;

    return 0;
}

At first I wouldn't have guessed correctly. But when you call pb->print() pb looks for matching function in D, that is a function with no parameter, but since B doesn't have a virtual function with that signature, the compiler doesn't bother to look at the table. Which is why 'wtf' gets printed. WTF

I'll give you another try because you upvoted me :P

#include <iostream>

struct B
{
    virtual void print(const char * msg = "wtf? -.-")
    {
        std::cout << msg << std::endl;
    }

    virtual ~B() {}
};

struct D : B
{
    void print(const char * msg = "Hello, World!")
    {
        std::cout << msg << std::endl;

        std::cout << "seriously, wtf? -.-" << std::endl;
    }
};

int main()
{
    B * pb = new D;

    pb->print();

    delete pb;

    return 0;
}

>> Copying bytes into an int punned as char* is only safe when the bytes being copied were acquired from another int.

>> That should fail on most processors.


I was looking for something along the lines of "Do I know that an int is 4 bytes?", "Do I know that '0' is 0x30 and that we're using 8-bit characters/ASCII?", and then after that, it was a question about endianness. If an int is 4 bytes, I don't see the problem with using strcpy. The string takes 4 bytes(3 plus the null terminator) and they're copied into the int and the int ends up being either 0x30313200 or 0x00323130 depending on endianness. Run it on a microcontroller or something where an int is two bytes and you get a seg fault.

Edited 5 Years Ago by VernonDozier: n/a

FacePalm. Tricky one. Its definitely because of the const char*. I'm not completely sure but the const char*msg in D::print is the value of the const char* in B::print, because initially, the base pointer is calling the function? I need some explanation.

If an int is 4 bytes, I don't see the problem with using strcpy.

I thought I already explained that. Unless this strcpy is the second part of a round trip of type punning an int, there's no guarantee that the result will be valid. Your other questions are moot because the code is severely broken in the first place.

the const char*msg in D::print is the value of the const char* in B::print, because initially, the base pointer is calling the function?

Yes.

The key to understanding this is to remember that the default argument is picked during compilation, while the function is picked at run time.

assert(sizeof(int) == 4); // no seg fault
    unsigned char check_5_for_overflow = 0x80;
    assert(check_5_for_overflow > '5'); // this check seems a tad silly, but what the heck?  Let's get rid of all possibility of negative numbers.

    // As far as I can tell, if things get to this point, this program can't crash and you'll always be able to guess the correct number.  I'm guaranteed to have a legitimate value in secret_number and it will be completely guessable by the printout whether we're using ASCII or any character mapping you want.

    int secret_number;
    int test_number;
    char* test_string = "345";

    strcpy((char*) &test_number, test_string);

    cout << test_string << " converts to " << test_number << endl;

    char* aString = "012";


    strcpy((char*) &secret_number, aString);

    int guess;

    cout << "Enter guess : ";
    cin >> guess;

    if(guess == secret_number)
    {
        cout << "You guessed right.\n";
    }

How's this?

>>I need some explanation.

Yep, at compile-time, because you call the function from a base-class pointer, the base-class function prototypes are looked at, the function "print" is found, the default parameter is picked up and inserted at the call-site. In other words, it becomes:

pb->print("wtf? -.-");

Then, at run-time, the virtual dispatch is done, and thus, the overridden function is called in the derived class. Now, of course, in this simple example, the virtual dispatch will not actually happen (and be optimized away), but the "as-if" rule applies, so the behaviour is the same.

Here is another one (pretty classic): What function gets called?

#include <iostream>

struct A { };

struct B : A { };

void f(const A*) { std::cout << "f(const A*)" << std::endl; };

template <typename T>
void f(T) { std::cout << "f<T>(T)" << std::endl; };

template <>
void f(const A*) { std::cout << "f<>(const A*)" << std::endl; };

template <>
void f(const B*) { std::cout << "f<>(const B*)" << std::endl; };

template <typename T>
void f(const T*) { std::cout << "f<T>(const T*)" << std::endl; };


int main() {
  B b;
  const A* a = &b;
  f(a);
  const B* br = &b;
  f(br);
  f(&b);
  return 0;
};

If a float cannot hold 999999999 (and it indeed cannot), the battle is already lost. Typecasting won't work. Float has 4 bytes, as does int. Since float can represent numbers that int cannot, it stands to reason that, being the same size, int will be able to represent numbers that float cannot. I simply picked one of them(999999999). The first time I wrote the program, I picked a number on accident that actually worked, so if you put the right number in there, the program will work. Replace "float" with "double" and the program works because doubles can represent any number that an int can represent.


Here's another one, slightly harder. Calculators are allowed. What should you guess? And do you care what kind of computer this program is running on? If so, why? And do you need any more information or is this snippet sufficient to guess correctly?

int secret_number;
    char* aString = "012";

    strcpy((char*) &secret_number, aString);

    int guess;

    cout << "Enter guess : ";
    cin >> guess;

    if(guess == secret_number)
    {
        cout << "You guessed right.\n";
    }

Should the code be able to be run as it was intended,808530432 would be a good guess.
Oops, I've just noticed that this question, practically has already been answered.
...

Edited 5 Years Ago by andrewll2: n/a

This article has been dead for over six months. Start a new discussion instead.