简体   繁体   中英

If variable a is a char array is char* p = &a defined behaviour in C++

I've always thought that:

char a[10];
char* p = &a;

Is wrong and that it should be one of the following instead:

char a[10];
char* p = a; // OR
char* p = &a[0];

I wish I could find the thread here on SO I was reading saying that p = &a; is valid, and it was in regard to the C language, not C++.

I've been thinking, obviously:

char* p = new char[10];
char* p1 = &p; // Is wrong

But when an array is created as a local in stack space it seems reasonable to my intuition that a , &a , and &a[0] are all the same value/address. I have to say, I've been following mostly C++ and not seen it done this way, which is why when I started to look into CI was quick to call it an error, but I'm sure it's not in C (well verification on that would be appreciated also). I'm just wondering if it's also the case in C++, because as far as I remember in C++ is usually done one of the other two ways and this way (if my imagination isn't playing tricks) seems to done in C.

Edit: This is a really dumb question. My confusion came from the fact that my Visual Studio compiler compiles it in C, but not for C++, so I thought there was a difference in the language in this respect. I won't delete the question because it already has an answer.

char a[10];
char* p = &a;

is indeed wrong in C.

In particular (all quotes refer to ISO 9899:1999 (C99) and all emphasis is mine):

6.7.8 (Initialization) / 11 says:

The initializer for a scalar shall be a single expression, optionally enclosed in braces. The initial value of the object is that of the expression (after conversion); the same type constraints and conversions as for simple assignment apply , taking the type of the scalar to be the unqualified version of its declared type.

6.5.16.1 (Simple assignment):

Constraints

  1. One of the following shall hold:
    • the left operand has qualified or unqualified arithmetic type and the right has arithmetic type;
    • the left operand has a qualified or unqualified version of a structure or union type compatible with the type of the right;
    • both operands are pointers to qualified or unqualified versions of compatible types , and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
    • one operand is a pointer to an object or incomplete type and the other is a pointer to a qualified or unqualified version of void , and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
    • the left operand is a pointer and the right is a null pointer constant; or
    • the left operand has type _Bool and the right is a pointer.

Only the bold part applies; we're not using any arithmetic or struct/union types, there's no void or _Bool and no null pointer constants.

The types in question are char * (pointer to char ) on the left and char (*)[10] (pointer to array[10] of char ) on the right. Compatibility of pointer types is defined as follows:

6.7.5.1 (Pointer declarators) / 2:

For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types .

The pointed-to types are char and char [10] , respectively.

But now we're stuck. There is 6.2.7 (Compatible type and composite type) / 1:

Two types have compatible type if their types are the same. Additional rules for determining whether two types are compatible are described in 6.7.2 for type specifiers, in 6.7.3 for type qualifiers, and in 6.7.5 for declarators.

char and char [10] are clearly not the same. All the declarator rules for compatible types in 6.7.5 say " For two pointer types to be compatible ... ", " For two array types to be compatible ... ", " For two function types to be compatible ... ", but there is no way for a non-array type to be compatible with an array type.

Thus the types are not compatible and char *p = &a violates a constraint in 6.5.16.1.

5.1.1.3 (Diagnostics):

A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint , even if the behavior is also explicitly specified as undefined or implementation-defined.

This means a warning or error message is required. If your compiler doesn't produce one, it's not an actual C compiler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM