No, references cannot be NULL in C++.1
Possible solutions include:
- using a pointer instead of a reference.
- having a dummy
Objectinstance that can be used to indicate "no object".
[1] From the C++11 standard:
Answer from Oliver Charlesworth on Stack Overflow[dcl.ref] [...] a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer, which causes undefined behavior.
In my textbook (Starting Out with Early Objects, Gaddis, Tony 9th Ed), in a chapter about c-strings and strings it gives this code example:
char name[] = "John Q. Public ";
char *p;
p = name;
cout << p << endl;
p = "Jane Doe";
cout << p << endl;
and then about 1 page later it goes on to say: A common mistake when using pointers to char as C-strings is using the pointer when it does not point to a properly allocated C-string . For example, the code
char *pname;
cout << "Enter your name: ";
cin >> pname;
what's wrong with the second set of code? When do we need to initialize a pointer to null and when can we skip it?
No, references cannot be NULL in C++.1
Possible solutions include:
- using a pointer instead of a reference.
- having a dummy
Objectinstance that can be used to indicate "no object".
[1] From the C++11 standard:
[dcl.ref] [...] a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer, which causes undefined behavior.
You cannot "solve" this. Use a pointer if you want to be able to have that member not point to anything.
References must be initialized to a real object, they cannot "point nowhere".
c - is it necessary to call pointer = NULL when initializing? - Stack Overflow
c++ - How to initialize a pointer to null - Stack Overflow
How to declare a varibale as null - C++ Forum
c - How to initialize a struct to null? - Stack Overflow
Is it possible to initialize a C pointer to NULL?
TL;DR Yes, very much.
The actual claim made on the guide reads like
On the other hand, if you use just the single initial assignment,
int *my_int_ptr = 2;, the program will try to fill the contents of the memory location pointed to bymy_int_ptrwith the value 2. Sincemy_int_ptris filled with garbage, it can be any address. [...]
Well, they are wrong, you are right.
For the statement, (ignoring, for now, the fact that pointer to integer conversion is an implementation-defined behaviour)
int * my_int_ptr = 2;
my_int_ptr is a variable (of type pointer to int), it has an address of its own (type: address of pointer to integer), you are storing a value of 2 into that address.
Now, my_int_ptr, being a pointer type, we can say, it points to the value of "type" at the memory location pointed by the value held in my_int_ptr. So, you are essentially assigning the value of the pointer variable, not the value of the memory location pointed to by the pointer.
So, for conclusion
char *x=NULL;
initializes the pointer variable x to NULL, not the value at the memory address pointed to by the pointer.
This is the same as
char *x;
x = NULL;
Expansion:
Now, being strictly conforming, a statement like
int * my_int_ptr = 2;
is illegal, as it involves constraint violation. To be clear,
my_int_ptris a pointer variable, typeint *- an integer constant,
2has typeint, by definition.
and they are not "compatible" types, so this initialization is invalid because it's violating the rules of simple assignment, mentioned in chapter §6.5.16.1/P1, described in Lundin's answer.
In case anyone's interested how initialization is linked to simple assignment constraints, quoting C11, chapter §6.7.9, P11
The initializer for a scalar shall be a single expression, optionally enclosed in braces. The initial value of the object is that of the expression (after conversion); the same type constraints and conversions as for simple assignment apply, taking the type of the scalar to be the unqualified version of its declared type.
The tutorial is wrong. In ISO C, int *my_int_ptr = 2; is an error. In GNU C, it means the same as int *my_int_ptr = (int *)2; . This converts the integer 2 to a memory address, in some fashion as determined by the compiler.
It does not attempt to store anything in the location addressed by that address (if any). If you went on to write *my_int_ptr = 5;, then it would try to store the number 5 in the location addressed by that address.
No, you don't have to set it to NULL, but some consider it good practice as it gives a new pointer a value that makes it explicit it's not pointing at anything (yet).
If you are creating a pointer and then immediately assigning another value to it, then there's really not much value in setting it to NULL.
It is a good idea to set a pointer to NULL after you free the memory it was pointing to, though.
No, there is no requirement (as far as the language is concerned) to initialize a pointer variable to anything when declaring it. Thus
T* ptr;
is a valid declaration that introduces a variable named ptr with an indeterminate value. You can even use the variable in certain ways without first allocating anything or setting it to any specific value:
func(&ptr);
Stroustroup always told us to us to us
TYPE *var = 0 ;
In ye olde days of C++ there was little standardization of libraries. Doing
TYPE *var = NULL ;
would often give different results when the definition of NULL was not standardized. Some compilers picked up the C definition.
C++ needed
#define NULL (0)
to work right while C headers generally had
#define NULL ((void*)0)
Thus, 0 became the accepted method for setting null pointers.
With the standard changes, there might be a shift to nullptr.
Using
int *p = nullptr;
is the best, I think.
When you use the typedef, it's OK to use value-initialization. But, you can't use:
int *p = int*{};
or
int *p = int*();
However, you can use:
int* p = nullptr;
ip q = nullptr;
Using nullptr to initialize is valid in both forms. Hence, it's better to use it to initialize pointers.
You can't. NULL is a pointer whose value is set to zero, but your mark and space properties are not pointer values. In your code as you have it, they will both be value types, allocated as part of your Pair struct.
Change the variables to Segment * instead of Segment, and you will be able to set them to NULL.
In order to intialise two sub-struct, which each contain a single int member to what gets closest to NULL, i.e. init all ints to "0" you can use this code:
#include <stdio.h>
typedef struct Segment {
int microseconds;
} Segment;
typedef struct Pair {
Segment mark;
Segment space;
} Pair;
int main(void)
{
Pair mark_and_space = { {0}, {0} };
return 0;
}
If you want to init them to NULL, assuming that you think of pointers, which is the only thing which can cleanly be intialised to NULL, then see the other answers, which basically say "if you want to init to pointer values, then init pointers, not ints".
Hi everyone,
I have an unusual question because I only saw people at work doing this and it confused me since I could not find anything about it on the internet.
So I have a basic understanding of c++ and as far as I know, c++ does not allow me to create a reference without initializing it. Meaning I can create an uninitialized variable if I want to but if I want a reference then I must give it a value to reference to, which makes sense.
int i; // ok
int& i; // error
int i = 0 // ok
int& j = i // ok
int i = 0 // ok
int& j = i // ok
Now I saw people at work doing exactly that and it confused me because the project builds and works successfully! Here is an example. Let's say we have a class A that has an Api member like the following
// header file
class A {A() = default;A(Api &api);
private:Api& api // does it make a difference if I declared the api attribute not as a reference?// (like this: Api api and let the rest as it is}
// cpp file
A::A(Api &api): api{api}
This is what confused me. The api private member/attribute is declared as a reference but it is not initialized so what does it reference exactly? As far as I know, references cannot be Null and must have a value so how can this declaration be possible?
My guess is that it is legit because the declaration is in the header file and the api member will be directly initialized in the constructor so eventually it will refer to something when the program runs and hence the compiler accept this. Am I right?
Can someone explain this to me and even better maybe tell me if this writing has any benefits or if they are using it. I tried to search on the internet about this but I didn't find any c++ code that uses this style of declaring references in the header file.