What does "int* p=+s;" do?
Asked Answered
A

5

63

I saw a weird type of program here.

int main()
{
    int s[]={3,6,9,12,18};
    int* p=+s;
}

Above program tested on GCC and Clang compilers and working fine on both compilers.

I curious to know, What does int* p=+s; do?

Is array s decayed to pointer type?

Adon answered 30/5, 2018 at 6:56 Comment(15)
That is exactly the purpose. This truck is also if you want to decay a lambda to a function pointerComradery
Plus before s can be safely omitted, it has no effectLively
s is pointer to int, there is no such thing as "array type" in C.Avirulent
There is array type in C. Try for example sizeof an array and a pointer.Armistead
@Avirulent arrays are completely different from pointers. For example if we have int b[2]; int a* = b; then int *c = b+1 and int *d = a + 1 will contain different valuesAjit
I would use int* p = &s[0]. But that's me. Actually, I would use std::array...Arthrospore
And please, if you're going to write code like this, at least write it "int* p = +s" (with spaces around the '='), to make it clear that this was intended to be a unary '+', unless you're trying to confuse anyone who has to maintain this code...Boothe
So you determine array size by using sizeof, but this is compile time operator and it works with statically allocated array. It is also possible to dinamically create array, what would be result of sizeof then?Avirulent
@LưuVĩnhPhúc: No they don't...?!? I agree arrays and pointers are different things, but your example is wrong.Cathar
It may be of anecdotal interest that the += operator originally was =+, which was changed presumably exactly because of the ambiguity with the unary +.Fumikofumitory
@LưuVĩnhPhúc @Cathar is right. in b+1 b decays to a pointer to its first element, i.e. is equal in type and value to a. If you want to point out (heh) the esistence of real arrays you could do something like int *p = b; int (*pa)[2] = &b; cout << "p: " << p << "pa: " << pa << "p+1: " << p+1 << "pa+1: " << pa+1 << endl; which should yield equal values for p and pa but different ones for the respective increments (because pa would point to the next array if there were one).Fumikofumitory
@Avirulent No, that is not possible. A pointer is a pointer. The area pointed to is generally unknown.Fumikofumitory
@ziza: You cannot apply sizeof to a dynamically allocated array because dynamically allocated array does not have a name. Also, this question is about C++, not about C. In C unary + is not applicable in this fashion, which would prevent the code from compiling. The question is exclusively about C++.Irrigation
@SeanBurton If you're going to write code like this then put int* p = std::decay(s);Cunningham
@Cunningham you meant std::decay_t<int>()?Concert
R
63

Built-in operator+ could take pointer type as its operand, so passing the array s to it causes array-to-pointer conversion and then the pointer int* is returned. That means you might use +s individually to get the pointer. (For this case it's superfluous; without operator+ it'll also decay to pointer and then assigned to p.)

(emphasis mine)

The built-in unary plus operator returns the value of its operand. The only situation where it is not a no-op is when the operand has integral type or unscoped enumeration type, which is changed by integral promotion, e.g, it converts char to int or if the operand is subject to lvalue-to-rvalue, array-to-pointer, or function-to-pointer conversion.

Raffaello answered 30/5, 2018 at 7:6 Comment(4)
Is it valid in C as well?Jenjena
@Jenjena Sorry I don't know. I'm not familiar with C, they're different language. :)Raffaello
@Jenjena Not really. In C, the unary + operator converts char to int like in C++, but putting it before an array, a pointer, or a function isn't valid in C.Labarbera
@DonaldDuck: I think you mean putting it before pointer-type values, including array and functions that decompose into such values and don't dereference the resulting pointer. Given double arr[20], someFunc(void), x; code could perfectly legitimately do x= +arr[5]; or x = +someFunc(); since the array and function are dereferenced.Madisonmadlen
P
25

Test this:

#include <stdio.h>
int main(){
    char s[] = { 'h', 'e', 'l', 'l', 'o' , ' ', 'w', 'o', 'r', 'l', 'd', '!'} ;
    printf("sizeof(s) : %zu,  sizeof(+s) : %zu\n", sizeof(s), sizeof(+s) ) ;
}

On my PC (Ubuntu x86-64) it prints:

sizeof(s): 12,  sizeof(+s) : 8

where

12 = number of elements s times size of char, or size of whole array
 8 = size of pointer
Promissory answered 30/5, 2018 at 8:37 Comment(2)
char s[] = "Hello worl"; [sic!] would have been more readable.Stu
"Hello worl!" would have an implicit '\0' at the endCecum
H
11

That's a unary plus symbol which has no practical effect here. For example:

#include <iostream>

int main() {
    int a[] = {1};

    std::cout << a << " " << +a << std::endl;
}

This prints the same address for both a and +a. The array is decayed to pointer as usual.

Note that, if it had been an unary minus -a instead then GCC would show the error:

error: wrong type argument to unary minus

Edit: Though it has no effect in OP's code, a and +a are not exactly same. Please refer to the answers by Khurshid Normuradov and songyuanyao for details.

Hebraize answered 30/5, 2018 at 7:5 Comment(3)
your answer is in constrast to most others by saying that "a unary plus symbol which has no practical effect here". However, std::cout << a; only prints the same because operator<< triggers the decay to a pointer as well, but still a is an array while +a is a pointer to the first elementIngurgitate
hm I think your answer is correct insofar as in OPs code the + really has no practical effect, because (if i am not mistaken) already the = makes the array decay. Nevertheless your answer can be mistunderstood as a being the same as +a.Ingurgitate
@user463035818 you are right. Other two answers cover that better than mine. So edited the answer a little bit to avoid such confusion.Hebraize
A
10

Is array s decayed to pointer type?

Yes.

What does int* p=+s; do?

Unary + operator forces the array to decay to a pointer.

C++ Standard, 5.3.1 Unary operators(P7):

The operand of the unary + operator shall have arithmetic, unscoped enumeration, or pointer type and the result is the value of the argument. Integral promotion is performed on integral or enumeration operands. The type of the result is the type of the promoted operand.

The unary + form (+s) forces the operand to be evaluated as a number or a pointer.

For more information, please see this stack overflow answer.

Adon answered 30/5, 2018 at 10:39 Comment(0)
N
0

Here unary + is just making *p to point the addresses of Integer array. Let's take two array s1 and s2

int s1[]={1,5,2};
int s2[]={2,5,2};

int *p=+s1;
p=+s2; 
printf("%d",(int)p[0]);

Output: 2

So in my point of view unary + is just making pointer p to point the array s beginning address.

Narcose answered 30/5, 2018 at 7:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.