Character array initialization with the first element being null

Viewed 3764

I was recently faced with a line of code and four options:

char fullName[30] = {NULL};
  1. A) First element is assigned a NULL character.

  2. B) Every element of the array is assigned 0 ( Zeroes )

  3. C) Every element of the array is assigned NULL

  4. D) The array is empty.

The answer we selected was option C, as, while the array is only initialized with a single NULL, C++ populates the rest of the array with NULL.

However, our professor disagreed, stating that the answer is A, he said:

So the very first element is NULL, and when you display it, it's displaying the first element, which is NULL.

The quote shows the question in its entirety; there was no other information provided. I'm curious to which one is correct, and if someone could explain why said answer would be correct.

4 Answers

The question is ill-defined, but Option B seems like the most correct answer.

The result depends on how exactly NULL is defined, which depends on the compiler (more precisely, on the standard library implementation). If it's defined as nullptr, the code will not compile. (I don't think any major implementation does that, but still.)

Assuming NULL is not defined as nullptr, then it must be defined as an integer literal with value 0 (which is 0, or 0L, or something similar), which makes your code equivalent to char fullName[30] = {0};.

This fills the array with zeroes, so Option B is the right answer.

In general, when you initialize an array with a brace-enclosed list, every element is initialized with something. If you provide fewer initializers than the number of elements, the remaining elements are zeroed.

Regarding the remaining options:

  • Option C is unclear, because if the code compiles, then NULL is equivalent to 0, so option C can be considered equivalent to Option B.

  • Option A can be valid depending on how you interpret it. If it means than the remaining elements are uninitialized, then it's wrong. If it doesn't specify what happens to the remaining elements, then it's a valid answer.

  • Option D is outright wrong, because arrays can't be "empty".

char fullName[30] = {NULL};

This is something that should never be written.

NULL is a macro that expands to a null pointer constant. A character - not a pointer - is being initialised here, so it makes no sense to use NULL.

It just so happens that some null pointer constants are also integer literals with value 0 (i.e. 0 or 0L for example), and if NULL expands to such literal, then the shown program is technically well-formed despite the abuse of NULL. What the macro expands to exactly is defined by the language implementation.

If NULLinstead expands to a null pointer constant that is not an integer literal such as nullptr - which is entirely possible - then the program is ill-formed.

NULL shouldn't be written in C++ at all, even to initialise pointers. It exists for backwards compatibility with C to make it easier to port C programs to C++.


Now, let us assume that NULL happens to expand to an integer literal on this particular implementation of C++.

Nothing in the example is assigned. Assignment is something that is done to pre-existing object. Here, and array is being initialised.

The first element of the array is initialised with the zero literal. The rest of the elements are value initialised. Both result in the null character. As such, the entire array will be filled with null characters.

A simple and correct way to write the same is:

char fullName[30] = {};

B and C are equally close to being correct, except for wording regarding "assignment". They fail to mention value initialisation, but at least the outcome is the same. A is not wrong either, although it is not as complete because it fails to describe how the rest of the elements are initialised.

If "empty" is interpreted as "contains no elements", then D is incorrect because the array contains 30 elements. If it is interpreted as "contains the empty string", then D would be a correct answer.

You are almost correct.

The professor is incorrect. It is true that display finishes at the first NULL (when some approaches are used), but that says nothing about the values of the remainder of the array, which could be trivially examined regardless.

[dcl.init/17.5]:: [..] the ith array element is copy-initialized with xi for each 1 ≤ i ≤ k, and value-initialized for each k < i ≤ n. [..]

However, none of the options is strictly correct and well-worded.

What happens is that NULL is used to initialise the first element, and the other elements are zero-initialised. The end result is effectively Option B.

Thing is, if NULL were defined as an expression of type std::nullptr_t on your platform (which it isn't, but it is permitted to be), the example won't even compile!

NULL is a pointer, not a number. Historically it has been possible to mix and match the two things to some degree, but C++ has tried to tighten that up in recent years, and you should avoid blurring the line.

A better approach is:

char fullName[30] = {};

And the best approach is:

std::string fullName;

Apparently, Your Professor is right, let's see how

char someName[6] = "SAAD";

how the string name is represented in memory:

0 1 2 3 4 5

S A A D

Array-based C string

The individual characters that make up the string are stored in the elements of the array. The string is terminated by a null character. Array elements after the null character are not part of the string, and their contents are irrelevant.

A "null string" is a string with a null character as its first character:

0 1 2 3 4 5

/0

Null C string

The length of a null string is 0.

Related