-5

I want to declare two or more pointers with same value with a single assignment operator in C/C++? The following code is an example:

List* a = NULL; 
List* b = NULL;
List* c = NULL;

Is there an equivalent in one line?

Edit: To clarify, I am looking for answer in both languages. I used a 'slash(/)' to separate out in the case of people willing to answer for one language. Thanks.

6
  • 7
    Pick a language. Commented Jan 29, 2017 at 3:39
  • 1
    "with a single assignment operator"? Do not trade initialization for assignment. And no, it can't be done with a single operator. Commented Jan 29, 2017 at 3:58
  • @AnT you are right on the initialization. Thanks. It's updated. Commented Jan 29, 2017 at 4:08
  • Any value or just null? Commented Jan 29, 2017 at 4:52
  • Any similar value. Commented Jan 29, 2017 at 5:57

4 Answers 4

5
List *a = NULL, *b = NULL, *c = NULL;

or

List *a, *b, *c;
a = b = c = NULL;

Note that in C++11 you should avoid the NULL macro in favor of nullptr.

Sign up to request clarification or add additional context in comments.

5 Comments

Why "or 0"??? "Classic" NULL in C++ is 0. And 0 suffers from the same problems as NULL, which is why nullptr was introduced in the first place. Moreover, since NULL can be defined as nullptr, the two best alternatives would actually be nullptr (best) and NULL, while 0 is the worst one that should be avoided.
Also, this is still three assignment operators, not one.
@AnT, Bjarne had his reasons for preferring 0 when he wrote his FAQ. In any case, nullptr is the clear winner.
@chris: Firstly, his reasons are purely superficial and personally-preferential (ther are no technical reasons to prefer 0 over NULL), so it desn't mean much. Secondly, his reasons were completely invalidated and obsoleted by C++11. 0 is now the worst option of the three and the reasons for that are technical, not personally-preferential. And the above poster is talking about C++11. The Bjarne's FAQ entry in now a historical oddity. It is no longer valid.
@AnT Fair enough, I changed it.
3

Strictly speaking, there are no assignments in your example - they are initialisations, since all three lines are declarations (actually, definitions in most contexts).

It is possible to wrap the example into a single line

 List *a = NULL, *b = NULL, *c = NULL;

but note that this repeats usage of "= NULL" for initialisation of each. Also note the need for extra asterisks (*) as, without these, not all the variables would be pointers. Note that placing multiple declarations or definitions in one line like this is considered poor style, since it is easy to forget one of the * or one of the initialisers, and get completely different results than intended (unitialised auto variables are not initialised to zero).

If you are willing to separate the declaration from initialisation, it is possible to do

 List *a, *b, *c;
 a = b = c = NULL;

If the definitions are globals, the default initialisation is zero, so

 // assume at file scope (outside any function)

 List *a;
 List *b;
 List *c;

 //  equivalently:   List *a, *b, *c;

does initialise all three to NULL. However this doesn't work work for initialising to other (non-zero) values. Within a function (or block) the same can be achieved by preceding the above with static.

In C++11, it is possible to do

 List *a{}, *b{}, *c{};

Instead of using three named variables, it is possible to use an array.

 List *a[3] = {NULL, NULL, NULL};

which can be simplified to

 List *a[3] = {NULL};

since the missing initialisers in this case will result in the corresponding elements being initialised to zero.

In C++11 and later (only) the array initialisation can - as pointed out by AnT in comment - be simplified to

 List *a[3] = {};

or to

 List *a[3]{};

In C++, it is often encouraged (unlike in C) to replace all usages of NULL with 0 or (from C++11) with nullptr.

4 Comments

... which can be simplified even further into List *a[3] = {}; or even List *a[3]{};
At least for C this List *a[3] = {NULL}; (if not in global scope) not necessarily initialises the 2nd and 3rd element to NULL. It sets their bytes to binary 0s, yes, but NULLs binary representation does not need to be 0s.
@alk - not so. The second and third elements are initialised to zero for the appropriate type (i.e. List *). For any pointer type, the value of zero is the NULL pointer, regardless of what the binary representation of NULL is.
@Peter: Correct. Need to clear this wrong assumption out of my head
1

With c++11, you can do this:

int* a{}, *b{}, *c{};

Comments

0

There is no way to declare and initialize multiple variables with a single assignment in C.

In C++17, you can get what you want using structured bindings:

auto [a, b, c] = std::make_tuple(ptr, ptr, ptr);

If you don't want to repeat the initialization value, you can make your own function to create a tuple by repeating a value N times:

template <typename T, std::size_t... Is>
auto repeat_impl(T const& x, std::index_sequence<Is...>) {
    return std::make_tuple((Is, x)...);
}

template <std::size_t N, typename T>
auto repeat(T const& x) {
    return repeat_impl(x, std::make_index_sequence<N>());
}

Use like so:

auto [a, b, c] = repeat<3>(ptr);

Though your specific example of initialization to null can be done using array:

auto [a, b, c] = std::array<List*, 3>();

In C++11, the best you can do is use tie to initialize the objects separately from their declarations:

List *a, *b, *c;
std::tie(a, b, c) = repeat<3>(ptr);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.