sizeof 'A'

K

Keith Thompson

pete said:
I think that (c + c) would be a better example of integer promotions,
than (c + 0) is,
because even if there were no such thing as "integer promotions",
the "usual arithmetic conversions" would still operate to make
(c + 0) be an expression of type int.

Agreed.
 
P

pete

CryptiqueGuy wrote:
In general, integer promotion occurs only when the operand having rank
less that int, is an operand of an arithmetic operator.

Shift operators do integer promotions.
 
B

Ben Pfaff

pete said:
Shift operators do integer promotions.

Isn't a shift operator an arithmetic operator? I am honestly
curious about the distinction you are making here, which is not
clear to me.
 
P

pete

pete said:
Shift operators do integer promotions.

Actually, there's a whole bunch of operators,
besides the arithmetic ones,
that cause the usual arithmetic conversions.
The usual arithmetic conversions
include the integer promotions.
 
P

pete

Ben said:
Isn't a shift operator an arithmetic operator? I am honestly
curious about the distinction you are making here, which is not
clear to me.

I consider it to be a bitwise operator.
Do you consider bitwise operators to arithmetic operators?
 
B

Ben Pfaff

pete said:
I consider it to be a bitwise operator.
Do you consider bitwise operators to arithmetic operators?

Ah, I understand what you are saying now. I am not sure whether
I agree or disagree. After all, I most often use shift operators
to do arithmetic, and their behavior is defined arithmetically.
But I definitely understand their operation in terms of their
effect on bits, too. I think that it may be a gray area.
Ultimately it is not too important, I guess.

C99's index has bitwise operators, shift operators, and other
kinds of operators as subcategories under "arithmetic
operators".
 
P

pete

pete said:
I consider it to be a bitwise operator.
Do you consider bitwise operators to arithmetic operators?

K&R2 has arithmetic operators in section 2.5
and bitwise operators in section 2.9.

The index of the C99 standard, groups shift operators
and bitwise operators under the entry for "arithmetic operators",
but the C90 standard index, doesn't.
 
P

Peter Nilsson

Eric Sosman said:
Peter said:
[...]
So let me turn that back at you. If it's going to happen
anyhow, again I ask, why would making 'A' a char cause
any harm?

What type should 'AB' have?

I think char, but my opinion is irrelevant. [I also think
C should have a separate byte type, and that char should
be implementation defined, only come in the plain varienty,
and be unsigned (like size_t); but that's not likely to
get through the Committee, whether the concept has merit
or not.]

Other than offering newbies a surprise -- and
let's face it, there are *many* things about C that
surprise newbies

Plenty of experienced programmers examining C for the
first time are surprised by the fact too. These days,
more and more programmers are encountering C++ before
the encounter C.
-- can you think of even one deleterious consequence of
'A' being an int?

I think '\xfe' having 4 different values is more of a
concern to me that it's type. Happy to agree that 'A'
being an int isn't really an issue for C programmers...
presently... 'user' defined type generic functions may
change that.

But the issue that sparked the sub thread was your
argument that character constants not having a character
type should not come as a surprise (to anyone).

Even if it's no more significant than the so-called
birthday paradox, it's still a surprise to many people.
 
E

Eric Sosman

Peter Nilsson wrote On 07/11/07 22:06,:
Eric Sosman said:
-- can you think of even one deleterious consequence of
'A' being an int?


I think '\xfe' having 4 different values is more of a
concern to me that it's type. [...]

'\xfe' is always 254 on systems where the behavior is
defined, that is, on systems where CHAR_MAX >= 254. On
other systems the behavior is undefined and there's no
reason to restrict the outcome to just three other values.
Could be any value at all, or nasal demons.

Argument for undefinedness:

6.4.4.4p6 says "[...] The numerical value of the
hexadecimal integer so formed specifies the value of
the desired character or wide character." The specified
value is therefore 254.

6.4.4.4p10 says "[...] If an integer character constant
contains a single character or escape sequence, its value is
the one that results when an object with type char whose
value is that of the single character or escape sequence is
converted to type int." Hence, the value of '\xfe' is the
result of converting a char object with value 254 to int.

On a system where CHAR_MAX < 254 no char object can
have the value 254, so 6.4.4.4p10 does not specify the
value of '\xfe' on those systems.

4p2 says "[...] Undefined behavior is otherwise
indicated [...] by the omission of any explicit definition
of behavior. There is no difference in emphasis among these
three; they all describe ``behavior that is undefined.''"
Since the derivation of an int value from '\xfe' is not
explicitly defined when CHAR_MAX < 254, the behavior is
undefined.

Observation: The int-ness of character constants is not
to blame for this situation. If they were of type char and
the conversion language were deleted from 6.4.4.4p10, you'd
still be stuck with the fact that no char can have a value
greater than CHAR_MAX. The value of '\xfe' (if it has one)
is not germane to the debate over character constants' types.
 
A

Army1987

['A' has type int]
Incredible! Splint 3.1.1:
test.c:77:27: Operands of != have incompatible types (int, char):
getchar() != '\n'

But wait a moment...
A character constant is used as an int. Use +charintliteral to allow
character constants to be used as ints. (This is safe since the actual type
of a char constant is int.)

(Right above that I read:
test.c:77:12: Operand of ! is non-boolean (int): !feof(stdin)
The operand of a boolean operator is not a boolean. Use +ptrnegate to allow !
to be used on pointers. (Use -boolops to inhibit warning)
Should I throw this program in the trash?)
 
R

Richard Bos

Army1987 said:
['A' has type int]
Incredible! Splint 3.1.1:
test.c:77:27: Operands of != have incompatible types (int, char):
getchar() != '\n'

Then Splint is, quite simply, wrong.
But wait a moment...
A character constant is used as an int. Use +charintliteral to allow
character constants to be used as ints. (This is safe since the actual type
of a char constant is int.)

(Right above that I read:
test.c:77:12: Operand of ! is non-boolean (int): !feof(stdin)
The operand of a boolean operator is not a boolean. Use +ptrnegate to allow !
to be used on pointers. (Use -boolops to inhibit warning)
Should I throw this program in the trash?)

Yes. Both those warnings are entirely spurious.

Or perhaps - I don't know Splint - you should turn off C++ mode. If
you're in C++ mode, that would explain at least the first warning, and
possibly - I don't know C++ this precisely, either, but it _is_ stricter
than C where type conversions are involved - the second. Never use any
program's C++ mode when you're handling C code.

Richard
 
A

Army1987

Army1987 said:
['A' has type int]
Incredible! Splint 3.1.1:
test.c:77:27: Operands of != have incompatible types (int, char):
getchar() != '\n'

Then Splint is, quite simply, wrong.
But wait a moment...
A character constant is used as an int. Use +charintliteral to allow
character constants to be used as ints. (This is safe since the actual type
of a char constant is int.)
It does know that '\n' has type int, but it chooses to ignore
that!
Yes. Both those warnings are entirely spurious.

Or perhaps - I don't know Splint - you should turn off C++ mode. If
you're in C++ mode, that would explain at least the first warning, and
possibly - I don't know C++ this precisely, either, but it _is_ stricter
than C where type conversions are involved - the second. Never use any
program's C++ mode when you're handling C code.
I don't think so, its manpage doesn't even mention C++, and the
file extension was .c. And I read:
-standard
The default mode. All checking done by weak, plus modifies check-
ing, global alias checking, use all parameters, using released
storage, ignored return values or any type, macro checking,
unreachable code, infinite loops, and fall-through cases. The
types bool, int and char are distinct. Old style declarations
are reported.

-checks
Moderately strict checking. All checking done by standard, plus
must modification checking, rep exposure, return alias, memory
management and complete interfaces.

-strict
Absurdly strict checking. All checking done by checks, plus modi-
fications and global variables used in unspecified functions,
strict standard library, and strict typing of C operators. A spe-
cial reward will be presented to the first person to produce a
real program that produces no errors with strict checking.
Considering it gave 22 warnings in a 121-line source file, even
after I fixed all the useful and relevant ones, (some of these are
useful in some situations but not in the one I had, and I didn't
feel like polluting my code with /*@iknowwhatiamdoing@*/ comments
and (void)fprintf(stderr, "What would I be supposed to do if this"
" failed?\n" casts), and I was using the default mode, I will not
dare to imagine what the -strict mode does...
 
D

Dietmar Schindler

Keith said:
All C expressions of integer type are of type int, unsigned int, or
something larger. Even the name of an object of type char is promoted
to int (or, very rarely, to unsigned int) unless it's the operand of
"&" or "sizeof". ...

No... promotion occurs only where stated by the standard. Examples of
statements with expressions where no promotion occurs:

char c = 'A', f(char c);

c; /* c not promoted */
f(c); /* neither argument nor return type promoted */
c = c; /* no promotion */
The only case where it makes any difference is when a character
constant is the operand of sizeof.

That it makes no difference does not say anything about how it is.
 
K

Keith Thompson

Dietmar Schindler said:
No... promotion occurs only where stated by the standard.
[...]

Yes, my error was pointed out (and I acknowledged it) some time ago.
 
D

Dietmar Schindler

Keith said:
Dietmar Schindler said:
No... promotion occurs only where stated by the standard.
[...]

Yes, my error was pointed out (and I acknowledged it) some time ago.

Thanks, now I've seen the posting by pete that I had missed. (Strangely,
it shows up in Google Groups, but not on the company's news server.)
 
D

David Thompson

There's no promotion when the left and right operands
of the assignment operator are of type char.
or when calling a prototyped function. Or when returning from a
function, but that's not an operator (which was the statement
upthread). (Formally there's no _promotion_ if the LHS/target is
non-char or more generally non-narrow; instead there's a _conversion_
which may happen to be the same as a promotion.)
There's no promotion when an expression of type char
is added to a pointer.
(including the pointer addition implied by subscripting)
The logical operators don't cause the promotion
of their operands,

Arguable. They say 'compare [un]equal to zero' but don't actually say
it's as-if == 0; if it is, that nominally promotes, but the promotion
has no visible effect on the results. The same applies to control
statements if, while, do-while, for.
and neither does the comma operator.
Right.

And as already noted, casts and expression-statements.

- formerly david.thompson1 || achar(64) || worldnet.att.net
 

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
473,780
Messages
2,569,611
Members
45,270
Latest member
TopCryptoTwitterChannels_

Latest Threads

Top