views:

167

answers:

7

Hi,

SDL provides me this struct:

typedef struct SDL_Rect {
    Sint16 x, y;
    Uint16 w, h;
} SDL_Rect;

I want to create a new SDL_Rect on the heap as class variable:

// Forward declaration
private:
    SDL_Rect *m_pcScreenRect;

And in the constructor I do this:

/* Screen Rectangle (for clearing) */
m_pcScreenRect = new SDL_Rect;
m_pcScreenRect->x = 0;
m_pcScreenRect->y = 0;
m_pcScreenRect->w = 800;
m_pcScreenRect->h = 600;
printf("Rect(x:%d, y:%d, w:%d, h:%d)\n", m_pcScreenRect->x, m_pcScreenRect->y, m_pcScreenRect->w, m_pcScreenRect->h);

Which prints Rect(x:0, y:0, w:800, h:600)
So this is correct.

Problem 1

But when I don't initialize x and y, it prints rubbish numbers like:

 Rect(x:-11280, y:63, w:800, h:600)
 Rect(x:25584, y:167, w:800, h:600)
 Rect(x:-11280, y:40, w:800, h:600)
 // This is just, run, terminate, run, terminate, ....

And I thought the default value for an int is 0?

Problem 2

In my gameloop, I have the same line to check the values of the SDL_Rect. In the loop I get results like this:

Clear (x:0, y:40, w:0, h:560)
Clear (x:0, y:99, w:0, h:501)
Clear (x:0, y:55, w:0, h:545)
Clear (x:0, y:55, w:0, h:545)
// Again: run, terminate, run, terminate....

When my constructor looks like this:

/* Screen Rectangle (for clearing) */
m_pcScreenRect = new SDL_Rect;
//m_pcScreenRect->x = 0;
//m_pcScreenRect->y = 0;
m_pcScreenRect->w = 800;
m_pcScreenRect->h = 600;

And I get normal results when I uncomment the two lines:

/* Screen Rectangle (for clearing) */
m_pcScreenRect = new SDL_Rect;
m_pcScreenRect->x = 0;
m_pcScreenRect->y = 0;
m_pcScreenRect->w = 800;
m_pcScreenRect->h = 600;

Does this problem something have to do with new or with the datatypes (Uint16, and a normal int). If it is with the datatypes, how to solve it?

Thanks would be very appreciated! (Haha!)

Thanks,
Any help would be very appreciated!


Extra Question:

I have to define all my variables in C++.
But from where do the random numbers come?

I'm using g++ and gcc in Linux.

+2  A: 

AFAIK, there are no default values for int and other non-class types in C++.

swegi
+1  A: 

In C++ you must always initialize all your variables.

danatel
Yes, that's true, but you don't need to do so explicitly for all types. If a class has a `std::string` member this will be initialized implicitly, too.
sbi
that is because std::string has a constructor, int, char, float, etc don't.
dbemerlin
+3  A: 

If you do not initialize a variable then it's value is undefined. There is no default value for heap-allocated integers.

dbemerlin
@dbemerlin: (and others) Thanks, for the info. For all of you +1!
Martijn Courteaux
That first sentence is not universally true. User-defined type will implicitly be initialized for you: `struct X { std::string m; }; X x;`.
sbi
+1  A: 

I think if you want your class data members to be initialized to a given value (including 0), you should just explicitly assign that in the constructor.

IIRC, in debug builds, MSVC fills allocated but uninitialized heap space with 0xCDCDCDCD pattern.

EmbeddedProg
However, `struct X { std::string m; X() {} };` is fine. It's only built-ins, where implicit initialization isn't done.
sbi
+5  A: 

In order to make use of the "default value for an int", you can use value initialization:

m_pcScreenRect = new SDL_Rect(); // this will initialize to zeros

Otherwise, the values are not defined.

To give more details: adding a constructor to this structure would be the best approach, but since it's in a third-party library which you (I suppose) cannot modify, you can either wrap it in your own class that provides a default constructor, or use value-initialization. To quote C++03 8.5/5,

To value-initialize an object of type T means:

  • if T is a class type with a user-declared constructor, then the default constructor for T is called

  • if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;

  • if T is an array type, then each element is value-initialized;

  • otherwise, the object is zero-initialized

In your case, SDL_Rect is a non-union class type without a user-declared constructor (second clause in this list), meaning value-initialization is performed for its non-static data memebers, and each of those data members falls under the "otherwise" clause, and is zero-initialized (which is defined as "if T is a scalar type, the object is set to the value of 0 (zero) converted to T;")

Cubbi
@Cubbi: So the diff is the `()`? Does this diff have a name? I want to learn about it.
Martijn Courteaux
@Martijn The name is "value initialization" (or "value-initialization"). It is the main difference between C++98 and C++03.
Cubbi
@Martijn: There is a difference for built-ins. Try to google for, if I remember the terms correctly, "value initialization" vs. "default initialization".
sbi
accepted because of the very appreciated information!
Martijn Courteaux
isn't that called a `default constructor`..?
Default
@Michael: `SDL_Rect` is a POD, it has only built-ins and no constructor. For such types, there's a difference between "default construction" and "value initialization" (or whatever the correct terms are).
sbi
@sbi. did not know. thanks :)
Default
@Martijn: Edited to include more details.
Cubbi
A: 

Put a constructor in your struct:

typedef struct SDL_Rect {
    SDL_Rect() { x = 0; y = 0; w = 0; h = 0; }

    Sint16 x, y;
    Uint16 w, h;
} SDL_
Adrian Regan
A: 

You have to initialize the values if you want them to have a default value. When you create a struct using new SDL_Rect, you just allocate the memory and the data contained in it is just the data which where at this place of the heap when you allocated, so this is roughly random. You can use a constructor to initialize the variables since the compiler automatically creates one if you reference it, i.e. new SDL_Rect()

kbok