Why is NULL undeclared? - c++

I have a problem with this struct contructor when I try to compile this code:
typedef struct Node
{
Node( int data ) //
{
this->data = data;
previous = NULL; // Compiler indicates here
next = NULL;
}
int data;
Node* previous;
Node* next;
} NODE;
when I come this error occurs:
\linkedlist\linkedlist.h||In constructor `Node::Node(int)':|
\linkedlist\linkedlist.h|9|error: `NULL' was not declared in this scope|
||=== Build finished: 1 errors, 0 warnings ===|
Last problem was the struct, but it worked fine when it was in my main.cpp, this time it's in a header file and is giving me this problem. I am using Code::Blocks to compile this code

NULL is not a built-in constant in the C or C++ languages. In fact, in C++ it's more or less obsolete, just use a plain literal 0 instead, the compiler will do the right thing depending on the context.
In newer C++ (C++11 and higher), use nullptr (as pointed out in a comment, thanks).
Otherwise, add
#include <stddef.h>
to get the NULL definition.

Do use NULL. It is just #defined as 0 anyway and it is very useful to semantically distinguish it from the integer 0.
There are problems with using 0 (and hence NULL). For example:
void f(int);
void f(void*);
f(0); // Ambiguous. Calls f(int).
The next version of C++ (C++0x) includes nullptr to fix this.
f(nullptr); // Calls f(void*).

Are you including "stdlib.h" or "cstdlib" in this file? NULL is defined in stdlib.h/cstdlib
#include <stdlib.h>
or
#include <cstdlib> // This is preferrable for c++

NULL isn't a native part of the core C++ language, but it is part of the standard library. You need to include one of the standard header files that include its definition. #include <cstddef> or #include <stddef.h> should be sufficient.
The definition of NULL is guaranteed to be available if you include cstddef or stddef.h. It's not guaranteed, but you are very likely to get its definition included if you include many of the other standard headers instead.

Don't use NULL, C++ allows you to use the unadorned 0 instead:
previous = 0;
next = 0;
And, as at C++11, you generally shouldn't be using either NULL or 0 since it provides you with nullptr of type std::nullptr_t, which is better suited to the task.

Related

implementation of the graph class <T> [duplicate]

I have a problem with this struct contructor when I try to compile this code:
typedef struct Node
{
Node( int data ) //
{
this->data = data;
previous = NULL; // Compiler indicates here
next = NULL;
}
int data;
Node* previous;
Node* next;
} NODE;
when I come this error occurs:
\linkedlist\linkedlist.h||In constructor `Node::Node(int)':|
\linkedlist\linkedlist.h|9|error: `NULL' was not declared in this scope|
||=== Build finished: 1 errors, 0 warnings ===|
Last problem was the struct, but it worked fine when it was in my main.cpp, this time it's in a header file and is giving me this problem. I am using Code::Blocks to compile this code
NULL is not a built-in constant in the C or C++ languages. In fact, in C++ it's more or less obsolete, just use a plain literal 0 instead, the compiler will do the right thing depending on the context.
In newer C++ (C++11 and higher), use nullptr (as pointed out in a comment, thanks).
Otherwise, add
#include <stddef.h>
to get the NULL definition.
Do use NULL. It is just #defined as 0 anyway and it is very useful to semantically distinguish it from the integer 0.
There are problems with using 0 (and hence NULL). For example:
void f(int);
void f(void*);
f(0); // Ambiguous. Calls f(int).
The next version of C++ (C++0x) includes nullptr to fix this.
f(nullptr); // Calls f(void*).
Are you including "stdlib.h" or "cstdlib" in this file? NULL is defined in stdlib.h/cstdlib
#include <stdlib.h>
or
#include <cstdlib> // This is preferrable for c++
NULL isn't a native part of the core C++ language, but it is part of the standard library. You need to include one of the standard header files that include its definition. #include <cstddef> or #include <stddef.h> should be sufficient.
The definition of NULL is guaranteed to be available if you include cstddef or stddef.h. It's not guaranteed, but you are very likely to get its definition included if you include many of the other standard headers instead.
Don't use NULL, C++ allows you to use the unadorned 0 instead:
previous = 0;
next = 0;
And, as at C++11, you generally shouldn't be using either NULL or 0 since it provides you with nullptr of type std::nullptr_t, which is better suited to the task.

Getting around compound literals in C++ to removing the warning

I'm working with libsystemd-dev (a C library) in my C++ application.
I get a gcc/clang pedantic warning
compound literals are a C99-specific feature
with this code:
#include <systemd/sd-bus.h>
void foo()
{
sd_bus_error err = SD_BUS_ERROR_NULL; // compound literals are a C99-specific feature
...
}
Looking at the <systemd/sd-bus.h> header file, I see:
typedef struct {
const char *name;
const char *message;
int _need_free;
} sd_bus_error;
#define SD_BUS_ERROR_MAKE_CONST(name, message) ((const sd_bus_error) {(name), (message), 0})
#define SD_BUS_ERROR_NULL SD_BUS_ERROR_MAKE_CONST(NULL, NULL)
This means I can solve the warning with:
#include <systemd/sd-bus.h>
void foo()
{
sd_bus_error err = {nullptr, nullptr, 0};
...
}
But is that a good idea? If the library changes, my code would need to change too so I feel that it's volatile. Is there really any problem with this warning? Is there a better way to get around it?
There is always the method of just using compiler flags to disable the warning, but I was wondering if there could be an encouraged method in-code to address this.
Omnifarious already hinted at one approach - use extensions inside a wrapper function. The slightly more robust method is to use an extern "C" wrapper function, in its own Translation Unit. Compile that whole Translation Unit as C11, without extensions.
This is generally more robust. Mixing code at source level requires advanced compiler support, whereas linking C and C++ is fairly straightforward.

Compiler errors with incorrect use of nullptr

I am trying the solution provided in this SO Q/ACompiler error while using shared_ptr with a pointer to a pointer and I am not able to use the solution provided in a proper way. I still get compilation errors on Ubuntu 18.04 with g++ version 7.3
Here is my minimum complete verifiable example to reproduce the problem
test.h
# include <memory>
using std::shared_ptr;
using std::unique_ptr;
struct DataNode
{
shared_ptr<DataNode> next;
} ;
struct ProxyNode
{
shared_ptr<DataNode> pointers[5];
} ;
struct _test_
{
shared_ptr<shared_ptr<ProxyNode>> flane_pointers;
};
test.cpp
#include <stdint.h>
#include "test.h"
shared_ptr<DataNode> newNode(uint64_t key);
shared_ptr<ProxyNode> newProxyNode(shared_ptr<DataNode> node);
struct _test_ test1;
int main(void)
{
test1.flane_pointers(nullptr);
shared_ptr<DataNode> node = newNode(1000);
}
shared_ptr<ProxyNode> newProxyNode(shared_ptr<DataNode> node) {
shared_ptr<ProxyNode> proxy(new ProxyNode());
return proxy;
}
shared_ptr<DataNode> newNode(uint64_t key) {
shared_ptr<DataNode> node(new DataNode());
return node;
}
This is the error I get
test.cpp: In function ‘int main()’:
test.cpp:11:31: error: no match for call to ‘(std::shared_ptr<std::shared_ptr<ProxyNode> >) (std::nullptr_t)’
test1.flane_pointers(nullptr);
^
What else have you tried ?
I tried initializing the nullptr in the header file as well
struct _test_
{
shared_ptr<shared_ptr<ProxyNode>> flane_pointers(nullptr);
};
But that did not work either. Where am I going wrong ?
My Goal
All I am trying to do is the following - I am trying to initialize flane_pointers which is a vector of pointers to a nullptr. The declaration has been made in a header file as to what type it is and I am trying to initialize it in a .cpp file. While doing that I get the above compilation errors.
flane_pointers(nullptr)
UPDATE
Could any of the answers explain whether the initialization provided in this Compiler error while using shared_ptr with a pointer to a pointer correct or not ?
std::shared_ptr<std::shared_ptr<ProxyNode> > ptr2ptr2ProxyNode(nullptr);
To me (and I am a newbie to C++) that initialization looks like a function call as well. Is that incorrect ?
On this line:
test1.flane_pointers(nullptr);
You're trying to call flane_pointers as though it were a member function. shared_ptr can't be called like a function, so you get the compiler error.
If you want to initialize flane_pointers, you can just assign to it:
test1.flane_pointers = nullptr;
Or alternatively, you could do the assignment when you create test1:
// Initialize test1 with a nullptr
_test_ test1{nullptr};
If your intent is to initialize flane_pointers to nullptr, you should use initialization of the below form:
shared_ptr<shared_ptr<ProxyNode>> flane_pointers = nullptr;
in struct _test_
or
test1.flane_pointers = nullptr;
in main.
The other form of initialization you are trying to do is interpreted as a function call in main and as a function declaration in struct _test_.
In the linked post,
std::shared_ptr<std::shared_ptr<ProxyNode> > ptr2ptr2ProxyNode(nullptr);
is in main and can only be interpreted as a variable declaration and not a function call because it does not have a function call syntax as the variable is preceded by the type std::shared_ptr >.
To avoid confusion, it is better (from C++11 onwards) to declare and initialize variables with the brace-enclosed initializer {}.
The line
test1.flane_pointers(nullptr);
is treated a function call. That's the source of the error. Use assignment instead.
test1.flane_pointers = nullptr;
And
shared_ptr<shared_ptr<ProxyNode>> flane_pointers(nullptr);
is not a valid form of in-member initialization. You may use
shared_ptr<shared_ptr<ProxyNode>> flane_pointers{nullptr};
or
shared_ptr<shared_ptr<ProxyNode>> flane_pointers = nullptr;

Compile error 'nullptr' undeclared identifier

I'm trying to compile a source with Visual Studio 2008 Express, but I'm getting this error:
Error C2065: 'nullptr' undeclared identifier.
My code:
if (Data == nullptr) {
show("Data is null");
return 0;
}
I read on Google that I should upgrade to Visual Studio 2010, but I don't want to do this because of the IntelliSense in Visual Studio 2008. Can this be repaired or replaced?
The error you are getting is because the compiler doesn't recognize the nullptr keyword. This is because nullptr was introduced in a later version of visual studio than the one you are using.
There's 2 ways you might go about getting this to work in an older version. One idea comes from Scott Meyers c++ book where he suggests creating a header with a class that emulates nullptr like this:
const // It is a const object...
class nullptr_t
{
public:
template<class T>
inline operator T*() const // convertible to any type of null non-member pointer...
{ return 0; }
template<class C, class T>
inline operator T C::*() const // or any type of null member pointer...
{ return 0; }
private:
void operator&() const; // Can't take address of nullptr
} nullptr = {};
This way you just need to conditionally include the file based on the version of msvc
#if _MSC_VER < 1600 //MSVC version <8
#include "nullptr_emulation.h"
#endif
This has the advantage of using the same keyword and makes upgrading to a new compiler a fair bit easier (and please do upgrade if you can). If you now compile with a newer compiler then your custom code doesn't get used at all and you are only using the c++ language, I feel as though this is important going forward.
If you don't want to take that approach you could go with something that emulates the old C style approach (#define NULL ((void *)0)) where you make a macro for NULL like this:
#define NULL 0
if(data == NULL){
}
Note that this isn't quite the same as NULL as found in C, for more discussion on that see this question: Why are NULL pointers defined differently in C and C++?
The downsides to this is that you have to change the source code and it is not typesafe like nullptr. So use this with caution, it can introduce some subtle bugs if you aren't careful and it was these subtle bugs that motivated the development of nullptr in the first place.
nullptr is part of C++11, in C++03 you simply use 0:
if (!Data)
When it's not recommended to edit sources, you can just give your c++ compiler appropriate define. For example, in CMakeLists.txt I've added line:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dnullptr=0")
And everything worked well

GCC compile error : declaration of ‘strlen’ must be available

My problem is that when I want to make a downloaded library I get some weird compile errors from GCC and the code that the compiler demands to correct seems just to be right.
The errors are all like this:
Catalogue.h:96: error: there are no
arguments to ‘strlen’ that depend on a
template parameter, so a declaration
of ‘strlen’ must be available
Here is the code around line 96:
GaCatalogueEntry(const char* name, T* data)
{
if( name )
{
_nameLength = (int)strlen( name ); // LINE 96
// copy name
_name = new char[ _nameLength + 1 ];
strcpy( _name, name ); // LINE 100: similar error
_data = data;
return;
}
_name = NULL;
_nameLength = 0;
_data = NULL;
}
What can I do to fix these compile errors?
You probably just need to include the header that contains the strcpy and strlen library functions.
#include <string.h>
or (preferably for C++)
#include <cstring>
In C++ the strlen() function is part of the string library, and it almost looks like the header file was not included.
Is it included anywhere?
include <string.h>
If not, try adding it and see if that fixes the problem.
The code is buggy. You are probably missing an #include <string.h>.
If you don't want to change the code, add -fpermissive to the compiler options. (See the GCC documentation.)
a declaration of ‘strlen’ must be available
Include string.h or <cstring> (C++) for the declaration of strlen().