NULL and nullptr and nil and Nil and NSNull

NULL and nullptr and nil and Nil and NSNull

[[129295]]

The declarations of NULL and nullptr can be found in the stddef.h file of Clang 6.0:

  1. #undef NULL
  2. #ifdef __cplusplus
  3. # if !defined(__MINGW32__) && !defined(_MSC_VER)
  4. #define NULL __null
  5. # else  
  6. #define NULL 0  
  7. # endif
  8. # else  
  9. # define NULL (( void *) 0 )
  10. #endif
  11. #ifdef __cplusplus
  12. # if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED)
  13. namespace std { typedef decltype(nullptr) nullptr_t; }
  14. using ::std::nullptr_t;
  15. #endif
  16. #endif

As early as 1972, when the C language was first created, the constant 0 had a dual identity as a constant and a null pointer. C used the preprocessor macro NULL to represent a null pointer, allowing NULL and 0 to represent a null pointer and the constant 0, respectively. NULL can be defined as ((void*)0) or 0.

C++ does not follow the rules of C and does not allow implicit conversion of void* to other types of pointers. In order for the code char* c = NULL; to compile, NULL can only be defined as 0. This decision makes it impossible to distinguish the semantics of the code when overloading functions:

  1. void foo( char *);
  2. void foo( int );

C++ suggests that NULL should be defined as 0, so foo(NULL); will call foo(int), which is not what the programmer wants and violates the intuitiveness of the code. The ambiguity of 0 causes confusion here.

C++11 introduces a new keyword to represent the null pointer constant: nullptr, which separates the concept of null pointer from the integer 0. The type of nullptr is nullptr_t, which can be implicitly converted to any pointer or member pointer type, and can also be compared with them for equality or inequality. However, nullptr cannot be implicitly converted to an integer, nor can it be compared with an integer.

For backward compatibility, 0 can still represent the null pointer constant.

  1. char * pc = nullptr; // OK  
  2. int * pi = nullptr; // OK  
  3. int i = nullptr; // error  
  4.    
  5. foo(pc); // calls foo(char *)  

PS: __MINGW32__ is a predefined macro for MinGW compiler. _MSC_VER is a predefined macro for Microsoft C/C++ compiler - cl.exe when compiling code. The value of _MSC_VER indicates the version of cl. This macro can also be used for conditional compilation when you need to write code for a specific version of cl.

nil and Nil

Objective-C

nil is defined as a null instance.

Nil is defined as the empty value of a class object (a null class)

nil and Nil have equivalent declarations in objc.h and MacTypes.h files:

  1. #ifndef Nil  
  2. # if __has_feature(cxx_nullptr)  
  3. #define Nil nullptr  
  4. # else  
  5. #define Nil __DARWIN_NULL  
  6. # endif  
  7. #endif  
  8. #ifndef nil  
  9. # if __has_feature(cxx_nullptr)  
  10. #define nil nullptr  
  11. # else  
  12. #define nil __DARWIN_NULL  
  13. # endif  
  14. #endif  

According to the description of __has_feature in Clang 3.7 document: "__has_feature evaluates to 1 if the feature is both supported by Clang and standardized in the current language standard or 0 if not", __has_feature(cxx_nullptr) is used to determine whether the nullptr feature in C++11 is supported. In Objective-C, both nil and Nil are defined by the __DARWIN_NULL macro. Press CMD and click to enter _types.h:

  1. #ifdef __cplusplus
  2. #ifdef __GNUG__
  3. #define __DARWIN_NULL __null
  4. # else   /* !__GNUG__ */  
  5. #ifdef __LP64__
  6. #define __DARWIN_NULL (0L)
  7. # else   /* !__LP64__ */  
  8. #define __DARWIN_NULL 0  
  9. #endif /* __LP64__ */  
  10. #endif /* __GNUG__ */  
  11. # else   /* !__cplusplus */  
  12. #define __DARWIN_NULL (( void *) 0 )
  13. #endif /* __cplusplus */  

Because Objective-C is not C++ code, the second to last line #define __DARWIN_NULL ((void *)0) is highlighted, which means that the final nil and Nil are essentially ((void *)0)

PS: In fact, if you only look at nil and Nil definition in Objective-C, it is not so troublesome. Just check "Constants->Null Values" in Objective-C Runtime Reference.

Swift

Swift 1.2 currently only has nil but no Nil. For security reasons, Swift has added the Optional type as a container. It's like a box that may contain a certain type of object, or it may be empty (nil). Boxes can also be nested or removed, but this is all based on safe parsing, binding, etc. Swift's nil is not the same as nil in Objective-C. In Objective-C, nil is a pointer to a non-existent object. In Swift, nil is not a pointer - it is a definite value used to indicate the absence of a value. Any type of optional value can be set to nil, not just object types.

PS: For more information about Optional types in Swift, please refer to my other blog post: Optionals and Optional Chaining in Swift

PS: Once upon a time, Swift’s nil was not a literal, but a unique instance of the NilType type. But that’s all history now.

NSNull

The definition of NSNull in NSNull.h is:

  1. @interface NSNull : NSObject <nscopying, nssecurecoding>
  2. + (NSNull *)null;
  3. @end</nscopying, nssecurecoding>

NSNull is a singleton with only one method, null, and is also used to represent null values. However, it appears in some scenarios where nil cannot be used to represent null values. For example, in NSArray and NSDictionary, nil represents the end of the array or dictionary (even if nil does not appear at the end, it will be cut off and the value after nil will be lost). In this case, only NSNull objects can be used to represent null values:

  1. NSNull *nullValue = [NSNull null ];
  2. NSArray *arrayWithNull = @[nullValue];
  3. NSLog(@ "arrayWithNull: %@" , arrayWithNull);
  4. // Output: "arrayWithNull: (<null>)"</null>  

Although NSNull is semantically equivalent to nil, it is not exactly equal to nil:

  1. id aValue = [arrayWithNull objectAtIndex: 0 ];
  2. if (aValue == nil) {
  3. NSLog(@ "equals nil" );
  4. }
  5. else   if (aValue == [NSNull null ]) {
  6. NSLog(@ "equals NSNull instance" );
  7. if ([aValue isEqual:nil]) {
  8. NSLog(@ "isEqual:nil" );
  9. }
  10. }
  11. // Output: "equals NSNull instance"  

<<:  iOS alternative memory management

>>:  Programmer Skill Hierarchy Model

Recommend

Lessons on how to make money that ordinary people can implement

Course List Lesson 1-The relationship between bac...

Keyword selection tips for bidding accounts!

SEM account optimization generally refers to the ...

Top 10 brand live streaming marketing models in 2021!

For most brands, live streaming has become a regu...

Eight "traps" to avoid in the programmer profession

[[229123]] Let's face it. Some of you got int...

Edge browser expands translation capabilities on Android platform

Following the screenshot feature, Microsoft conti...

Understand the meaning of matrix rank and determinant in one article

As an engineering student, we have been using lin...

How to choose a Baidu bidding outsourcing company?

As the popularity of e-commerce continues to incr...

Formula for brand marketing and promotion!

"Bringing goods" has become a topic tha...

What is traffic hijacking in paid promotion? Why are landing pages hacked?

My friend Lao Wang complained to me this morning,...

The latest media operation tools in history (121 types)

The core essence of new media is actually tools ....

How does Zuoyebang operate private domain traffic?

For the education industry, 2020 is definitely a ...