473,395 Members | 1,468 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

cast vs. suffixes

If you want to explicitly state the type of an integer constant, you
basically have two options. Either you use an explicit cast, as in:
(unsigned int) 1234
or you use the UL suffixes, as in:
1234UL
Are there -- in general -- any semantic differences in using casts
versus suffixes?
--Ralf

Jan 20 '06 #1
12 2649
Ralf wrote:
If you want to explicitly state the type of an integer constant, you
basically have two options. Either you use an explicit cast, as in:
(unsigned int) 1234
This, at compiler's choice, can be left to be evaluated at
run-time. I'd still expect a good optimiser to do it at
compile-time. So, potentially, you get nasty bugs if you mistype
your constants.
or you use the UL suffixes, as in:
1234UL
This is always done at compile time. Here, mistyped constants
are caught while still in vitro.
Are there -- in general -- any semantic differences in using casts
versus suffixes?
--Ralf


There may also be other implications which escape me at the moment.

Cheers

Vladimir
--
My e-mail address is real, and I read it.
Jan 20 '06 #2


Ralf wrote On 01/20/06 12:52,:
If you want to explicitly state the type of an integer constant, you
basically have two options. Either you use an explicit cast, as in:
(unsigned int) 1234
or you use the UL suffixes, as in:
1234UL
Are there -- in general -- any semantic differences in using casts
versus suffixes?


Yes. `(unsigned int)1234' is not a constant: it is
an expression consisting of the operator `(unsigned int)'
applied to the constant operand `1234'. The type of the
expression's result is `unsigned int' and the value is
one thousand two hundred thirty-four.

`1234UL' is a constant. Its type is `unsigned long'
and its value is one thousand two hundred thirty-four.
(Note that the type of this constant is not the same as
the type of the earlier expression.)

One place this makes an easily-observable difference
is in the preprocessor. Since the preprocessor operates
at an early stage of compilation before types "exist,"
it cannot evaluate cast operators -- since casts are all
about type conversions and there aren't any types yet,
there's really nothing the preprocessor can do with them.

Consider the following code:

#include <stdio.h>

int main(void) {
#if 1234UL > 0
puts ("#1: as expected");
#else
puts ("#1: unbelievable!");
#endif

#if (unsigned int)1234 > 0
puts ("#2: as expected");
#else
puts ("#2: unbelievable!");
#endif

return 0;
}

Without compiling and running it, can you predict the
output? (Warning: I've asked a trick question.)

--
Er*********@sun.com

Jan 20 '06 #3
Ralf wrote:

If you want to explicitly state the type of an integer constant, you
basically have two options. Either you use an explicit cast, as in:
(unsigned int) 1234
or you use the UL suffixes, as in:
1234UL
Are there -- in general -- any semantic differences in using casts
versus suffixes?


What happens on a system with 16-bit integers with:

(long)65537

versus

65537L

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Jan 20 '06 #4

"Eric Sosman" <er*********@sun.com> wrote in message
news:dq**********@news1brm.Central.Sun.COM...


Ralf wrote On 01/20/06 12:52,:
If you want to explicitly state the type of an integer constant, you
basically have two options. Either you use an explicit cast, as in:
(unsigned int) 1234
or you use the UL suffixes, as in:
1234UL
Are there -- in general -- any semantic differences in using casts
versus suffixes?


Yes. `(unsigned int)1234' is not a constant: it is
an expression consisting of the operator `(unsigned int)'
applied to the constant operand `1234'. The type of the
expression's result is `unsigned int' and the value is
one thousand two hundred thirty-four.

`1234UL' is a constant. Its type is `unsigned long'
and its value is one thousand two hundred thirty-four.
(Note that the type of this constant is not the same as
the type of the earlier expression.)

One place this makes an easily-observable difference
is in the preprocessor. Since the preprocessor operates
at an early stage of compilation before types "exist,"
it cannot evaluate cast operators -- since casts are all
about type conversions and there aren't any types yet,
there's really nothing the preprocessor can do with them.

Consider the following code:

#include <stdio.h>

int main(void) {
#if 1234UL > 0
puts ("#1: as expected");
#else
puts ("#1: unbelievable!");
#endif

#if (unsigned int)1234 > 0
puts ("#2: as expected");
#else
puts ("#2: unbelievable!");
#endif

return 0;
}

Without compiling and running it, can you predict the
output? (Warning: I've asked a trick question.)

--
Er*********@sun.com


It produces the "expected" result, of course :-). I will try it
momentarily.
Jan 20 '06 #5
OK, I guess that #if (unsigned int)1234 > 0 doesn't 'preprocess' that
is, it will yield an error.
Actually, I wanted to write (unsigned long) instead of (unsigned int),
but my fingers were quicker than my brain.
My wrong example actually makes quite a difference, even to the
compiler because of the 'usual arithmetic conversion' rules.
But let's assume that I had written (unsigned long)1234. Would there be
any semantic difference from the
*compiler's* point of view?
(You made a good point about the preprocesser; I would have never
thought about that)

Jan 20 '06 #6
Eric Sosman wrote:

Ralf wrote On 01/20/06 12:52,:
If you want to explicitly state the type of an integer constant, you
basically have two options. Either you use an explicit cast, as in:
(unsigned int) 1234
or you use the UL suffixes, as in:
1234UL
Are there -- in general -- any semantic differences in using casts
versus suffixes?

Yes. `(unsigned int)1234' is not a constant: it is
an expression consisting of the operator `(unsigned int)'
applied to the constant operand `1234'. The type of the
expression's result is `unsigned int' and the value is
one thousand two hundred thirty-four.

`1234UL' is a constant. Its type is `unsigned long'
and its value is one thousand two hundred thirty-four.
(Note that the type of this constant is not the same as
the type of the earlier expression.)

One place this makes an easily-observable difference
is in the preprocessor. Since the preprocessor operates
at an early stage of compilation before types "exist,"
it cannot evaluate cast operators -- since casts are all
about type conversions and there aren't any types yet,
there's really nothing the preprocessor can do with them.

Consider the following code:

#include <stdio.h>

int main(void) {
#if 1234UL > 0
puts ("#1: as expected");
#else
puts ("#1: unbelievable!");
#endif

#if (unsigned int)1234 > 0
puts ("#2: as expected");
#else
puts ("#2: unbelievable!");
#endif

return 0;
}

Without compiling and running it, can you predict the
output? (Warning: I've asked a trick question.)


"# (unsigned int)1234 ..." is a compile error

"missing binary operator before token "int"

So basically, your observation is correct; the preprocessor has no
problems with the first set of #if/#else and borks on the second because
the types ("unsigned int" or whatever) doesn't yet exist.

--
N Mulangi [Remove "lovesspam" from email address to reply]

Javascript/DOM Help, Tutorials, Reference:
http://www.HyperFaqs.org/
Jan 20 '06 #7
Kenneth Brody <ke******@spamcop.net> writes:
Ralf wrote:
If you want to explicitly state the type of an integer constant, you
basically have two options. Either you use an explicit cast, as in:
(unsigned int) 1234
or you use the UL suffixes, as in:
1234UL
Are there -- in general -- any semantic differences in using casts
versus suffixes?


What happens on a system with 16-bit integers with:

(long)65537

versus

65537L


I presume you mean 16-bit ints. (The term "integer" includes all the
signed and unsigned integral types, from char to long long; "int" is
just one of those types.)

So, assuming int is 16 bits, type int will most likely have a range of
-32768 .. +32767, and unsigned int will most likely have a range of
0 .. 65535. (Padding bits and representations other than 2's-complement
can cause variations, but we'll ignore that.) Type long is guaranteed
to have a range of at least -2147483647 .. +2147483647.

The type of a decimal integer constant (like 65537) is the first of
the following in which is value can be represented:

int
long int
long long int (C99)

So if int is 16 bits, 65537 is already of type long, and the cast does
nothing. If int is 32 bits, 65537 is of type int, and the cast
converts it from int to long.

On any implementation, both (long)65537 and 65537L are of type long
and have the value 65537. The difference, as discussed previously, is
that 65537L is a constant and (long)65537 is not.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 20 '06 #8


Ralf wrote On 01/20/06 14:08,:
OK, I guess that #if (unsigned int)1234 > 0 doesn't 'preprocess' that
is, it will yield an error.
Actually, I wanted to write (unsigned long) instead of (unsigned int),
but my fingers were quicker than my brain.
My wrong example actually makes quite a difference, even to the
compiler because of the 'usual arithmetic conversion' rules.
But let's assume that I had written (unsigned long)1234. Would there be
any semantic difference from the
*compiler's* point of view?
(You made a good point about the preprocesser; I would have never
thought about that)


Both `(unsigned long)1234' and `1234UL' are
expressions, the first consisting of an operator
and an `int' operator and the second consisting
only of an `unsigned long' constant. They'll have
the same type and the same value, and I can't think
of any circumstance where they'd behave differently
(once past the preprocessor).

--
Er*********@sun.com

Jan 20 '06 #9


N Mulangi wrote On 01/20/06 14:25,:
Eric Sosman wrote:
[...]
Consider the following code:

#include <stdio.h>

int main(void) {
#if 1234UL > 0
puts ("#1: as expected");
#else
puts ("#1: unbelievable!");
#endif

#if (unsigned int)1234 > 0
puts ("#2: as expected");
#else
puts ("#2: unbelievable!");
#endif

return 0;
}

Without compiling and running it, can you predict the
output? (Warning: I've asked a trick question.)

"# (unsigned int)1234 ..." is a compile error

"missing binary operator before token "int"

So basically, your observation is correct; the preprocessor has no
problems with the first set of #if/#else and borks on the second because
the types ("unsigned int" or whatever) doesn't yet exist.


Right. Even worse, the keywords `unsigned' and `int'
don't yet exist. As far as the preprocessor is concerned,
they're just identifiers that don't happen to be macros
and therefore aren't subject to macro substitutions. The
rules for #if specify that any identifiers remaining after
macro expansion (other than `defined') are evaluated as
zeroes, so the directive becomes the equivalent of

#if ( 0 0 ) 1234 > 0

.... and that's not a properly-formed expression.

By the way, I'm not suggesting that anybody in his
right mind would actually write the #if directives I showed
in my sample. It's still a concern, though, because of
things like

void f(void) {
#if MAX_WIDGETS > 100
/* large buffer: use dynamic memory */
struct widget *widgets =
malloc(MAX_WIDGETS * sizeof *widgets);
if (widgets == NULL) die();
#else
/* safe to use small auto buffer */
struct widget widgets[MAX_WIDGETS];
#endif

/* ... work with the array of widgets ... */

#if MAX_WIDGETS > 100
free (widgets);
#endif
}

This sort of thing is fine and dandy if MAX_WIDGETS
is #define'd as 42 or 1024u, but will cause exactly the
problem you spotted if defined as `(unsigned)99'.

--
Er*********@sun.com

Jan 20 '06 #10
Eric Sosman a écrit :

#if (unsigned int)1234 > 0
puts ("#2: as expected");
#else
puts ("#2: unbelievable!");
#endif

ITYM
if ((unsigned int)1234 > 0)
puts ("#2: as expected");
else
puts ("#2: unbelievable!");
--
A+

Emmanuel Delahaye
Jan 20 '06 #11
Kenneth Brody a écrit :
What happens on a system with 16-bit integers with:

(long)65537
compiler warning 'too big for the type' or the like...

versus

65537L


This is the Good and Portable Way.

--
A+

Emmanuel Delahaye
Jan 20 '06 #12
Emmanuel Delahaye <em***@YOURBRAnoos.fr> writes:
Kenneth Brody a écrit :
What happens on a system with 16-bit integers with:
(long)65537


compiler warning 'too big for the type' or the like...


No, if int can't hold the value 65537, then the literal is of type
long.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 20 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

21
by: dogu | last post by:
I'm missing something and need a push in the right direction. If I create a php file with the following content, and call it via a browser, it works as expected. <?php echo "hello world"; ?> ...
0
by: Aaron W. West | last post by:
Fun with CAST! (Optimized SQLServerCentral script posts) I found some interesting "tricks" to convert binary to hexadecimal and back, which allow doing 4 or 8 at a time. Test code first: --...
2
by: Jeffrey E. Forcier | last post by:
This seems like a dead simple question, as it's so rudimentary I can't believe it hasn't been addressed before. I'm using the time.strftime() function (actually the mxDateTime implementation, but...
17
by: Hazz | last post by:
In this sample code of ownerdraw drawmode, why does the '(ComboBox) sender' line of code need to be there in this event handler? Isn't cboFont passed via the managed heap, not the stack, into this...
59
by: Lennart Björk | last post by:
Hi All, I have a tiny program: <!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>MyTitle</title> <meta...
5
by: Frederick Gotham | last post by:
Before I begin, here's a list of assumptions for this particular example: (1) unsigned int has no padding bits, and therefore no invalid bit- patterns or trap representations. (2) All types have...
9
by: Hamish M | last post by:
Hi I am interested in opinions on this topic. I have heard that a suffix is not a good solution and type casts are much better for example. ...
4
by: Abraham Andres Luna | last post by:
hello everyone, i seen some code that declared a float like this: float f = 0.5F; is there a chart somewhere that oulines all the letters for the data types. i'm not sure what keyword to...
16
by: JoseMariaSola | last post by:
How may operators and operands does (typename) expression has? I'd say one operator, the cast operator, and two operands: typename and expression. But everywhere I read, cast is categorized as...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.