Why does "char *ptr={'R','E','D','\0'};" gives too many warnings while "char *ptr="RED";" works fine?

StackOverflow https://stackoverflow.com/questions/16436523

문제

Consider the following code:

#include<stdio.h>

int main()
{
   char *ptr={'R','E','D','\0'};
   //char *ptr="RED";
}

It shows the following list of warnings:

warning: initialization makes pointer from integer without a cast|
warning: excess elements in scalar initializer|
warning: (near initialization for 'ptr')|

But if works fine if I comment out the first statement and activate the second statement (which is commented out in my code).

Why is it so?Why isn't a pointer to the same array not assigned to ptr in the first case,just as it is in the second case?What is the rigorous technical reason for this?

도움이 되었습니까?

해결책

In 6.7.9 (11) [of the N1570 draft, identical in 6.7.8 (11) of C99], it is specified that

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.

By providing more than a single expression in

char *ptr={'R','E','D','\0'};

you're violating a "shall" requirement and invoke undefined behaviour (4 (2)):

If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined.

That out of the way, this particular kind of undefined behaviour usually mainfests as the compiler ignoring all but the first expression - except for the generation of the

warning: excess elements in scalar initializer|

and treats the code as if it was

char *ptr = {'R'};

then, which unsurprisingly leads to the

warning: initialization makes pointer from integer without a cast|

since 'R' is an integer and not a pointer.

On the other hand,

char *ptr = "RED";

is perfectly fine because the array(1) "RED" is converted to a pointer to its initial element in the initialisation, like it would be for assignment.

(1) String literals are arrays, not pointers, as told in section 6.4.5 (6):

In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals. The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. For character string literals, the array elements have type char, and are initialized with the individual bytes of the multibyte character sequence. For UTF−8 string literals, the array elements have type char, and are initialized with the characters of the multibyte character sequence, as encoded in UTF−8.

(wide string literals are arrays of type wchar_t[N], char16_t[N] or char32_t[N], depending on whether they are prefixed with L, u or U.)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top