What happens when I set the value of an integer to NULL? I print it out / debug it, i get the value zero.

Even I can use the NULL assigned integer to initiate another integer.

Well, then what is the point of being NULL? Why set it to zero?

int main()
{
	int x = NULL;
	int u = x; //I thought, this line should through an error

	cout << x << " "  << u << endl;

	return 0;
}

output:
0 0

Recommended Answers

All 28 Replies

I also noticed something,

int main()
{
	int x;
	int u = x;

	return 0;
}

This code runs perfectly fine on GCC 4.4.1 but doesn't on VCC, that comes with VS 2008 express edition.

:S This is confusing!

>>Well, then what is the point of being NULL? Why set it to zero?

In c++ NULL is just a macro (see this link if you don't know what a macro is) that is defined to be 0. Normally NULL is used to initialize pointers to a known address so that the pointer is never confused with some valid address. NULL means nothing at all when used with integers because 0 is a valid integer value. So it makes no sense to assign NULL to an integer. c and c++ languages do not have any way to tell us that an integer is uninitialized, or has no value at all.

commented: Awesome, exactly what I was looking for. +2

I also noticed something,

int main()
{
	int x;
	int u = x;

	return 0;
}

This code runs perfectly fine on GCC 4.4.1 but doesn't on VCC, that comes with VS 2008 express edition.

:S This is confusing!

That's a behavior that is compiler-dependent. I don't think there is anything in the standard that says what should happen.

Some compilers, such as GCC, automatically initialize integers to 0 while others, such as VC++, leave the variable uninitialized and issue a warning making you responsible for the initialization.

It is not advisable to rely on such compiler "quirks" in your code. If the compiler your using doesn't have this "quirk", you leave the door wide open for some rather insidious bugs to creep into your code.

Your best bet is to get into the good habit of initializing all variables when you declare them. That way, you always know what the value of the variable will be and your program's behavior will be more predictable and more likely to be what you intended.

..That way, you always know what the value of the variable will be and your program's behavior will be more predictable and more likely to be what you intended.

yes, that's I was going for. I thought, going under the NULL umbrella can be a good approach. But now I think, 0 or -1 is a good choice, though it might be totally problem dependent.

Thanks!

> Some compilers, such as GCC, automatically initialize integers to 0

Correction. No compiler initialize an auto variable to anything. Every compiler initialize static variables to 0 (this is mandated by the Standard).

> issue a warning
At a proper warning level GCC will issue a warning as well.

Some compilers, such as GCC, automatically initialize integers to 0

No, GCC doesn't initialize ints to 0. I run following program three times:

#include <iostream>
int main(){
   int a;
   std::cout<<a<<'\n';
}

On GCC 4.4.5 it gives me -121776192, -1217650700 and -1218613260. Only global variables are initialized automatically to 0, just like standard says (I think).

> issue a warning
At a proper warning level GCC will issue a warning as well.

What means by proper warning level?

Use -Wall (for gcc) or /W4 (for VC++) as a compiler switch to turn on the highest warning level. With lower warning levels set, the compiler suppresses warnings it considers "less serious." You should almost always compile with the highest setting.

Well, I use CodeBlocks and VS, how they setup themselves after default installation. How do I know or change modify those setting?

Is this something that I have to add as command line argument?

No, there's a setting under both C::B and VS (but if you were compiling from the command line you could add the switches)

In VS2010: ProjectMenu/<projname>Properties/Configuration Properties/CC++/WarningLevel change to /Wall (I'm not sure what the difference between W4 and Wall is) -- I think this changes it for the project, not sure how to do it globally.

In C::B (v. 6931) Settings/CompilerDebugger/GlobalCompilerSettings/CompilerSettingsTab/ 4th option down

commented: Thanks :) +2

"what is the point of being NULL? Why set it to zero?"

Sometimes, you need to know if a number (say a) has a correct value of 0, or it has nothing yet.

You may want to use, for example, if a is null, then doing job A, or else, doing job B.

I do not think any compiler is doing the right thing by automatically initialize integers to 0. It is just like to initialize any object to a EMPTYCLASS but not to NULL.

There is no such animal as a NULL integer in either C or C++ languages to indicate that the integer has no value. There are languages that have that concept, but not in C or C++. C compilers will often produce either warnings or errors if you try to assign NULL to an integer because NULL may be defined as (void *)0 which is a pointer.

As previously mentioned C and C++ compilers initialize global variableds to 0. Other variables are left uninitialized so your program has to initialize them.

I ended you using a bool value, isNULL, to indicate if the integer data member of that class has any valid data or not. But, it looks messy.

Shouldn't there would be a way to detect uninitialized variable?

>> Shouldn't there would be a way to detect uninitialized variable

Maybe there should, but there isn't. There are no invalid values in C or C++ lanauges. And isNULL will not return any valid information because there is no way to detect whether an integer contains valid data or not. You can only guess.

In c/c++ its a good idea to initialize variables to some known state. Unintialized variables causing problem has kept many a programmer debugging for hours.

In C++ Null is defined as 0. See section on "Should I use NULL or 0?" for some words of wisdom from the master himself.

http://www2.research.att.com/~bs/bs_faq2.html

commented: Awesome Link :D +2

>> In c/c++ its a good idea to initialize variables to some known state.

I cannt do that because 'that known value' can be a valid input.

>> And isNULL will not return any valid information because there is no way to detect whether an integer contains valid data or not. You can only guess.

I am handling this manually.I am assigning an int value and then setting the isNULL value to false. Other then that isNULL remains true.

Is this a bad approach? I am using this while inserting value to BST.

Let see some code for what your trying to do

I am going to implement "Red Black Tree" using this as a base.

#include<iostream>
using namespace std;

class Node
{
public:
	int data;	
	Node *preNode;
	Node *postNode;
	Node *parentNode;
	bool isEmpty;
	bool isNULL;

	Node(bool null = false)
	{
		this->preNode = NULL;
		this->postNode = NULL;
		this->parentNode = NULL;
		this->isEmpty = true;
		if(null)this->isNULL = true;
		else this->isNULL = false;
	}	
};

Node rootNode;
Node *traversingNode;

void insert(int _insertData);
void inorderTraverse(Node *tempNode);

int main()
{
	insert(4);	
	insert(2);	
	insert(3);	
	insert(1);	
	insert(6);	
	insert(5);	
	insert(7);	

	inorderTraverse(&rootNode);
	return 0;
}
void insert(int _insertData)
{
	traversingNode = &rootNode;

	while(traversingNode->isEmpty != true && traversingNode->isNULL != true)
	{
		if(_insertData <= traversingNode->data)	
			traversingNode = traversingNode->preNode;
		else 
			traversingNode = traversingNode->postNode;		
	}
	
	traversingNode->data = _insertData;
	traversingNode->isEmpty = false;
	traversingNode->isNULL = false;	
	traversingNode->preNode = new Node(true);
	traversingNode->preNode->parentNode = traversingNode;
	traversingNode->postNode = new Node(true);
	traversingNode->postNode->parentNode = traversingNode;
}

void inorderTraverse(Node *tempNode)
{
	if(!tempNode->preNode->isNULL) inorderTraverse(tempNode->preNode);
		cout << tempNode->data;
	if(!tempNode->postNode->isNULL) inorderTraverse(tempNode->postNode);	
}

The pointers to nodes initialized to NULL make sense.

But what/how is the isNull used for?

At the end of every leaf there should be 2 Null node of Black color.

I wanted to use a node(an instance of Node) which has isNULL value set to true. So, its easier for me to detect that i have reached at the end of a simple path.

It will also help to change the color of that NULL node(to whatever the situation desires) when I will insert a new node with red color.

if isNull means all nodes are null, then an alternative is to have method to check nodes are null

I don't know, checking if something equals to NULL always feels uncomfortable. Maybe sometime ago I faced some problem, so i took previous approach.

what else are the rooms for improvement?

#include<iostream>
using namespace std;

class Node
{
public:
	int data;	
	Node *preNode;
	Node *postNode;
	Node *parentNode;
	bool isEmpty;

	Node()
	{
		this->preNode = NULL;
		this->postNode = NULL;
		this->parentNode = NULL;
		this->isEmpty = true;
	}	
};

Node rootNode;
Node *traversingNode;

void insert(int _insertData);
void inorderTraverse(Node *tempNode);

int main()
{
	insert(4);	
	insert(2);	
	insert(3);	
	insert(1);	
	insert(6);	
	insert(5);	
	insert(7);	

	inorderTraverse(&rootNode);
	return 0;
}
void insert(int _insertData)
{
	traversingNode = &rootNode;

	while(traversingNode->isEmpty != true)
	{
		if(_insertData <= traversingNode->data)	
			traversingNode = traversingNode->preNode;
		else 
			traversingNode = traversingNode->postNode;		
	}
	
	traversingNode->data = _insertData;
	traversingNode->isEmpty = false;	
	traversingNode->preNode = new Node();
	traversingNode->postNode = new Node();
}

void inorderTraverse(Node *tempNode)
{
	if(tempNode->preNode->preNode) inorderTraverse(tempNode->preNode);
		cout << tempNode->data;
	if(tempNode->postNode->postNode) inorderTraverse(tempNode->postNode);	
}

I dont know, but i always has a bad feeling about checking whether checking if it is null or not.

if(tempNode->preNode->preNode) inorderTraverse(tempNode->preNode);

Some questions to ask yourself.
1. class or structure?
2. Inside the class, you do not need this-> to reference data members
3. Initialize in constructor rather than assign

For example

struct Node
{
    int data;
    Node *preNode;
    Node *postNode;
    Node *parentNode;
    bool isEmpty;

    Node()
    : data(0)
    , preNode(NULL)
    , postNode(NULL)
    , parentNode(NULL)
    , isEmpty(true)
    {
    } 
};

Some questions to ask yourself.
1. class or structure?
2. Inside the class, you do not need this-> to reference data members
3. Initialize in constructor rather than assign

For example

1. I actually asked around a lot about it. All say its all public and that's all private and if you use only POD then go for struct.

And when I am using C++ compiler, replacing struct keyowrd with class doesn't change a thing(except public private issue).

But no one tells if there is any technical difference between or not.

3. What is the advantage of this approach?

A structure is a class where members are public by default, besides that technically speaking there are same. However by convention, structures are used to represent simple data structures and classes for more expressive functionality.

For this simple application, it’s not a big deal, but meticulous attention to Constructors and Destructors, including the initialization and order of initialization will save you hours of debugging time in the future.

>> For this simple application, it’s not a big deal, but meticulous attention to Constructors and Destructors, including the initialization and order of initialization will save you hours of debugging time in the future.

But isn't the initialization is assigning individual values to independent items. Isn't values are the only thing that matters? If the values remain same in both cases, why different methods may yield different result?

sorry if I sound silly. :(

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.