This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: the standard rules for assigning types to integer constants in C


On Wed, Aug 22, 2001 at 12:10:32PM +0100, Bernd Schmidt wrote:
> On Tue, 21 Aug 2001, Zack Weinberg wrote:
> 
> >
> > ... don't seem to match what has been implemented in GCC.
> >
> > C99 6.4.4.1, paragraph 5, describes how the type is to be chosen:
> >
> > 	The type of an integer constant is the first of the corresponding
> > 	list in which its value can be represented.
> >
> > 	Suffix		Decimal Constant		Octal or Hex Constant
> > 	------		----------------		---------------------
> > 	none		int				int
> > 							unsigned int
> > 			long				long
> > 							unsigned long
> > 			long long			long long
> > 							unsigned long long
> 
> What if a decimal constant only fits into an unsigned long long?

Overflow, which probably winds up being some category of undefined
behavior, which would let us get away with making the type unsigned
long long.  However, I am dubious about that.  Unlike some parts
of the standard, this one is perfectly clear: unsuffixed decimal
constants are signed, no exceptions.

Just for the heck of it I implemented the standard rules exactly
as stated.  The behavior on overflow was to cram the value into a
long long (well, a widest_integer_literal_type, but they're the
same on this target) which has the effect of silently converting
it to a negative number.

The only effect visible to the test suite is that we stop complaining
about

long long i = 18446744073709551615;

being either a "decimal constant which is so long that it is
unsigned", or a "integer constant [which] is signed with -traditional,
unsigned in standard C".

[The idea of issuing this sort of -Wtraditional warning for long
long is kinda dubious, IMO, it should be "traditional C does not
support long long" and leave it at that.]

Also, even at -O0 there is no difference in the generated code - the
extra-wide type doesn't cause any efficiency problems.

> > The table we're using for no suffix is:
> >
> > 	Decimal			Octal or Hex
> > 	-------			------------
> > 	int			int
> > 				unsigned int
> > 	long			long
> > 	unsigned long		unsigned long
> > 	long long		long long
> > 	unsigned long long	unsigned long long
> > 	intmax_t?		intmax_t?
> >
> > My question is twofold:
> >
> > 1: Were these rules different in C89?  If so, what were they?
> 
> C89 didn't have long long.  I believe I recall seeing a comment that explained
> the problem - for better compatibility we didn't want to go to long long
> automatically if a number didn't fit into a long.  But I may misremember this.

There weren't any comments in the code I was hacking up.

> > 2: What, if anything, should we do about this?
> 
> Make it dependent on which version of the standard the user has selected?

technically, in strict C89 mode, long long shouldn't be accessible at all.
In default mode I don't see any particular reason not to use the C99 rules.

zw


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]