why

D

Darklight

The program demonstrates the use of unions program taken from a book
why if i change one character in a program i get the following error

list10-6.c:14:20: warning: multi-character character constant
list10-6.c: In function `main':
list10-6.c:14: warning: overflow in implicit constant conversion

the program is below the offending line, is line 14 the character
is $ changed to £

/* LIST10-6..C EXAMPLE OF USING MORE THAN ONE UNION MEMBER AT A TIME */
#include<stdio.h>

int main(void)
{
union shared_tag{
char c;
int i;
long l;
float f;
double d;
}shared;

(14); shared.c = '$';

printf("\nchar c = %c",shared.c);
printf("\nint i = %d",shared.i);
printf("\nlong l = %ld",shared.l);
printf("\nfloat f = %f",shared.f);
printf("\ndouble d = %f",shared.d);

shared.d = 123456789.8765;

printf("\nchar c = %c",shared.c);
printf("\nint i = %d",shared.i);
printf("\nlong l = %ld",shared.l);
printf("\nfloat f = %f",shared.f);
printf("\ndouble d = %f\n",shared.d);

return 0;
}
 
R

Richard Bos

Darklight said:
The program demonstrates the use of unions program taken from a book
why if i change one character in a program i get the following error

list10-6.c:14:20: warning: multi-character character constant
list10-6.c: In function `main':
list10-6.c:14: warning: overflow in implicit constant conversion

the program is below the offending line, is line 14 the character
is $ changed to £
union shared_tag{
char c;
int i;
long l;
float f;
double d;
}shared;
(14); shared.c = '$';

So, erm... you change a one-character character constant to a
two-character character constant, the compiler warns you that you now
have a multi-character character constant, and you're asking why?
Because you have created a multi-character character constant, that's
why.
As for the overflow warning, character constants have type int, for
hysterical reasons. All one-character character constants which
represent execution chars are guaranteed to map to an int value which is
small enough to fit in a char. Multi-character character constants,
however, have implementation-defined value; apparently, in your
compiler's case, some of these are too wide to fit in a char, and your
two-character character constant is one of those.

Richard
 
D

Dan Pop

In said:
The program demonstrates the use of unions program taken from a book
why if i change one character in a program i get the following error

The problem is not that you change one character but that you replace one
character by two characters in a character constant.
list10-6.c:14:20: warning: multi-character character constant

Crystal-clear, isn't it?
list10-6.c: In function `main':
list10-6.c:14: warning: overflow in implicit constant conversion

A direct consequence of the first diagnostic: the value of the
multi-character character constant is out of the range representable
by type char, on that particular compiler.
the program is below the offending line, is line 14 the character
is $ changed to £

/* LIST10-6..C EXAMPLE OF USING MORE THAN ONE UNION MEMBER AT A TIME */
#include<stdio.h>

int main(void)
{
union shared_tag{
char c;
int i;
long l;
float f;
double d;
}shared;

(14); shared.c = '$';

shared.c has type char, a character constant has type int. It is,
therefore, possible, for a multi-character character constant to have a
value outside the range of the type char. Or even for '$', because $
is not part of the basic source character set.

Dan
 
D

Dan Pop

In said:
As for the overflow warning, character constants have type int, for
hysterical reasons.

No historical reasons involved, unless you consider the integral
promotions a historical reason.

Dan
 
K

Keith Thompson

In <[email protected]>


No historical reasons involved, unless you consider the integral
promotions a historical reason.

Given a declaration

char ch;

the expression ch has type char, which is converted by the integer
promotions to int (or conceivably unsigned int). But the expression
'x' is inherently of type int, because the standard says so; there is
no promotion from char to int. (sizeof(ch) yields 1; sizeof('x')
yields the same value as sizeof(int).)

The standard could as easily have said that 'x' is of type char (which
is then subject to the integer promotions). (In fact, this is what
C++ does.)

If you're saying that the fact that character constants have type int
has some more indirect relationship to the integer promotions, you
could make a case for that, but I think that would still qualify as
historical reasons.
 
R

Richard Tobin

The problem is not that you change one character but that you replace one
character by two characters in a character constant.


Crystal-clear, isn't it?

Not necessarily. the OP's post was encoded in UTF-8:

So the thing he changed it to may have appeared to him as, and been
intended as, one character (a pound sign). Most likely his compiler
assumes that the input is in latin-1, so the two bytes are interpreted
as two characters (A with circumflex followed by pound).

-- Richard
 
R

Richard Bos

Well, duh.
If you're saying that the fact that character constants have type int
has some more indirect relationship to the integer promotions, you
could make a case for that, but I think that would still qualify as
historical reasons.

Exactly. There's no real reason for it today; no language designer would
devise the integral promotions today, and certainly wouldn't make a
character constant a different type from a character variable; but for
historical reasons, both still exist in C. The only reason I can think
of not to remove them from ISO C, either the previous or the next
version, is that there was and still is too much code which relies on
them.

Richard
 
D

Dan Pop

In said:
Well, duh.


Exactly. There's no real reason for it today; no language designer would
devise the integral promotions today,

Please explain why dmr devised them in the first place? Why were they
more necessary back then than today?

Dan
 
D

Dan Pop

In said:
Given a declaration

char ch;

the expression ch has type char, which is converted by the integer
promotions to int (or conceivably unsigned int). But the expression
'x' is inherently of type int, because the standard says so; there is
no promotion from char to int. (sizeof(ch) yields 1; sizeof('x')
yields the same value as sizeof(int).)

Right. So what?
The standard could as easily have said that 'x' is of type char (which
is then subject to the integer promotions).

But why do such a thing? The compiler has to allocate memory for ch,
but it doesn't have to allocate memory for 'x'. So, it makes sense
for the size of ch to be 1, even if it is automatically promoted to int
when used, but it would make absolutely no sense for 'x' to have a type
that is NEVER used.
(In fact, this is what C++ does.)

For reasons that apply *exclusively* to C++.
If you're saying that the fact that character constants have type int
has some more indirect relationship to the integer promotions,

Nope, it has as a direct relationship as you can get. ch is an object
and it occupies a well defined amount of memory, 'x' can only be used in
expressions under the type int (even if its intrinsic type would be char).
So, what's the point of giving 'x' type char, if its mere appearance in
(practically) any C context automatically promotes it to int?
Is there any intrinsic reason for having sizeof 'x' == 1 in C?
If not, WHY should character constants have type char?
you
could make a case for that, but I think that would still qualify as
historical reasons.

The only way to invoke historical reasons is by claiming that the integral
promotions themselves are a historical feature of the language that
doesn't make any sense today. In which case, the question that naturally
arises is: why did they make more sense 30 years ago than they make
today?

Dan
 
D

Dan Pop

In said:
Not necessarily. the OP's post was encoded in UTF-8:

Which is not supported by Usenet, just as it is (obviously) not supported
by his compiler. If the OP wanted to shoot himself in the foot, he
brilliantly succeeded.

Any text editor using UTF-8 as an external encoding *behind the user's
back* is broken by design. If the OP configured it this way, he got
exactly what he deserved.

UTF-8 may very well be the encoding of the future, but it's far from
being the encoding expected by most current tools.

Dan
 
K

Keith Thompson

Nope, it has as a direct relationship as you can get.

It would be a more direct relationship if the integer promotion rules
somehow required character constants to have type int. They don't,
but they do imply that it only rarely matters whether a character
constant has type char or type int (I think sizeof is the only context
where it matters).
ch is an object
and it occupies a well defined amount of memory, 'x' can only be used in
expressions under the type int (even if its intrinsic type would be char).
So, what's the point of giving 'x' type char, if its mere appearance in
(practically) any C context automatically promotes it to int?
Is there any intrinsic reason for having sizeof 'x' == 1 in C?
If not, WHY should character constants have type char?

Personally, I find it counterintuitive that character constants don't
have a character type (and, similarly, that enumerators are of type
int rather than of an enumerated type). Apparently I'm not alone in
this, since the C FAQ specifically addresses it in question 8.9. But
I can understand why the choice was made, and your point is a valid
one.

Thanks for the clarification.
 
D

Dan Pop

In said:
(e-mail address removed) (Dan Pop) writes:
[...]
Nope, it has as a direct relationship as you can get.

It would be a more direct relationship if the integer promotion rules
somehow required character constants to have type int.

The integer promotion rules can't be supposed to define the types of any
C syntactic elements, can they?
They don't,
but they do imply that it only rarely matters whether a character
constant has type char or type int (I think sizeof is the only context
where it matters).

The difference matters only in the pathological case where sizeof(int)==1
and it is not clear to what type char is promoted (int or unsigned).
Personally, I find it counterintuitive that character constants don't
have a character type

It *is* counterintuitive, until you start thinking about it. Before
joining c.l.c I was convinced that they have type char, BTW.
this, since the C FAQ specifically addresses it in question 8.9. But
I can understand why the choice was made, and your point is a valid
one.

Thanks for the clarification.

You're welcome,
Dan
 
K

Keith Thompson

The difference matters only in the pathological case where sizeof(int)==1
and it is not clear to what type char is promoted (int or unsigned).

Yes, but that's not quite what I meant.

What I meant was that, because of the integer promotion rules, a
C-like language in which character constants have type char would
differ visibly from C only in the result of the sizeof operator
applied to a character constant; in all other contexts, the value
would be promoted to int anyway (or, as you point out, to unsigned
int).

Then again, there's rarely any reason to apply the sizeof operator to
a character constant. It could be used to distinguish between C and
C++ (though that would fail when sizeof(char)==1, and the __cplusplus
macro is a much better way to do that), or it could show up in a macro
expansion.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,145
Messages
2,570,824
Members
47,369
Latest member
FTMZ

Latest Threads

Top