473,387 Members | 1,590 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,387 software developers and data experts.

strange use of format specifier in printf

Here in this thread
http://groups.google.co.in/group/com...b0dbf76f3e02e3

Tydr Schnubbis in 3rd reply used %d for printing char's...isn't it
wrong?

Jun 23 '06 #1
18 2400

Money wrote:
Here in this thread
http://groups.google.co.in/group/com...b0dbf76f3e02e3

Tydr Schnubbis in 3rd reply used %d for printing char's...isn't it
wrong?


No. It will print them in decimal though, not as characters.

I suggest you look up what char is promoted to when passed as an
argument.

Tom

Jun 23 '06 #2

"Money" <sp*********@gmail.com> wrote in message
news:11*********************@m73g2000cwd.googlegro ups.com...
Here in this thread
http://groups.google.co.in/group/com...b0dbf76f3e02e3

Tydr Schnubbis in 3rd reply used %d for printing char's...isn't it
wrong?

Yes. This has to be the presumption against a hyperlink versus the OP
taking time to tailor his argument to the forum. ciao, f
Jun 23 '06 #3
Money wrote:
Here in this thread
http://groups.google.co.in/group/com...b0dbf76f3e02e3

Tydr Schnubbis in 3rd reply used %d for printing char's...isn't it
wrong?


On a platform with signed 'char' type, when 'char' values are passed as
arguments for '...' (ellipsis) parameters, they are first promoted to 'int'
values. So it's 'int' values that are actually passed. And there's nothing wrong
with using '%d' format specifier with 'int' values.

On a platform with unsigned 'char' type, it is possible that 'int' is not large
enough to hold all values of 'char' and 'char' will be promoted to 'unsigned
int' instead. In this particular case the code would lead to undefined behavior,
since it is illegal to use '%d' format specifier with 'unsigned int' values.

--
Best regards,
Andrey Tarasevich
Jun 23 '06 #4
Tom St Denis wrote:
Money wrote:
Here in this thread
http://groups.google.co.in/group/com...b0dbf76f3e02e3

Tydr Schnubbis in 3rd reply used %d for printing char's...isn't it
wrong?


No. It will print them in decimal though, not as characters.

I suggest you look up what char is promoted to when passed as an
argument.

Tom


But we are telling printf to print 32-bits(on my system), and char is
not 32-bits(I know it can be but atleast it's not on my system)

Jun 23 '06 #5

Andrey Tarasevich wrote:
Money wrote:
Here in this thread
http://groups.google.co.in/group/com...b0dbf76f3e02e3

Tydr Schnubbis in 3rd reply used %d for printing char's...isn't it
wrong?


On a platform with signed 'char' type, when 'char' values are passed as
arguments for '...' (ellipsis) parameters, they are first promoted to 'int'
values. So it's 'int' values that are actually passed. And there's nothing wrong
with using '%d' format specifier with 'int' values.

On a platform with unsigned 'char' type, it is possible that 'int' is not large
enough to hold all values of 'char' and 'char' will be promoted to 'unsigned
int' instead. In this particular case the code would lead to undefined behavior,
since it is illegal to use '%d' format specifier with 'unsigned int' values.

--
Best regards,
Andrey Tarasevich


Thanks..I got it.

Jun 23 '06 #6
Money wrote:
I suggest you look up what char is promoted to when passed as an
argument.


But we are telling printf to print 32-bits(on my system), and char is
not 32-bits(I know it can be but atleast it's not on my system)


AHEM
I suggest you look up what char is promoted to when passed as an
argument.


Thanks for playing the usenet game. Can you now play the research
game?

Tom

Jun 23 '06 #7
>> I suggest you look up what char is promoted to when passed as an
argument.

Tom


But we are telling printf to print 32-bits(on my system), and char is
not 32-bits(I know it can be but atleast it's not on my system)


But what is char promoted to when passed as an argument on your
system?

Gordon L. Burditt
Jun 23 '06 #8
Andrey Tarasevich wrote:
...
On a platform with unsigned 'char' type, it is possible that 'int' is not
large enough to hold all values of 'char' and 'char' will be promoted
to 'unsigned int' instead. In this particular case the code would lead
to undefined behavior, since it is illegal to use '%d' format specifier
with 'unsigned int' values.


On such a hosted implementation, you'll likely find considerably
more problems than just printing a char. The C standards seem
to let the QoI gods rule out the possibility of such implementations
existing.

[Different story for freestanding implementations though. Real
implementations with CHAR_MAX == UINT_MAX exist, though
none which include <stdio.h> support, AFAIK.]

--
Peter

Jun 23 '06 #9
How about this solution

#define BIG_ENDIAN 0
#define LITTLE_ENDIAN 1

int TestByteOrder()
{
int x = 0x0001;
char *y = (char *) &x;
return(y[0] ? LITTLE_ENDIAN : BIG_ENDIAN);
}

Jun 23 '06 #10
Money said:
How about this solution

#define BIG_ENDIAN 0
#define LITTLE_ENDIAN 1

int TestByteOrder()
{
int x = 0x0001;
char *y = (char *) &x;
return(y[0] ? LITTLE_ENDIAN : BIG_ENDIAN);
}


This fails to identify middle-endian systems.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 23 '06 #11
Richard Heathfield wrote:
Money said:
How about this solution

#define BIG_ENDIAN 0
#define LITTLE_ENDIAN 1

int TestByteOrder()
{
int x = 0x0001;
char *y = (char *) &x;
return(y[0] ? LITTLE_ENDIAN : BIG_ENDIAN);
}


This fails to identify middle-endian systems.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)

Just forgetting about any other ordering except these two. Will it work
fine if char is more than 8 bits?

Jun 23 '06 #12
"Money" <sp*********@gmail.com> writes:
Richard Heathfield wrote:
Money said:
> How about this solution
>
> #define BIG_ENDIAN 0
> #define LITTLE_ENDIAN 1
>
> int TestByteOrder()
> {
> int x = 0x0001;
> char *y = (char *) &x;
> return(y[0] ? LITTLE_ENDIAN : BIG_ENDIAN);
> }


This fails to identify middle-endian systems.


Just forgetting about any other ordering except these two. Will it work
fine if char is more than 8 bits?


Maybe.

A very minor point: I'd write the initializer for x as "0x1" or just
"1". The three leading zeros seem to imply that int is 16 bits, which
of course it may or may not be.

If char is at least 16 bits, then it's possible that sizeof(int)==1;
in that case, int has no meaningful byte order, but your function will
return LITTLE_ENDIAN.

If int has at least CHAR_BIT padding bits at its lowest address, your
function will BIG_ENDIAN if the padding bits happen to be set to 0, or
possibly some meaningless result if the padding bits are set to some
arbitrary value.

Your function tests the byte order of type int. It's not
inconceivable that other integer types could have different byte
orders.

None of these problems are likely to turn up on any modern hosted
system.

--
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.
Jun 23 '06 #13
Richard Heathfield posted:
Money said:
How about this solution

#define BIG_ENDIAN 0
#define LITTLE_ENDIAN 1

int TestByteOrder()
{
int x = 0x0001;
char *y = (char *) &x;
return(y[0] ? LITTLE_ENDIAN : BIG_ENDIAN);
}


This fails to identify middle-endian systems.

Start off with an unsigned integer, and set its value to zero.

Then set its second LSB to 1 (achieve this by taking 1 and shifting it
CHAR_BIT places to the left, and then OR-ing it with the original
variable).

Then set its third LSB to 2. Then set its forth LSB to 3. And so on.

Then use a char pointer to go through the unsigned integer's bytes. The
byte with the value 0 is the LSB. The byte with the value 1 is the second
LSB. And so on. (But beware of padding within the unsigned integer!).

I've already written such code many times but I'm working off a laptop
and don't have my code directory with me...
Jun 23 '06 #14
Keith Thompson wrote:
If char is at least 16 bits, then it's possible that sizeof(int)==1;
in that case, int has no meaningful byte order, but your function will
return LITTLE_ENDIAN.
How is it possible for sizeof(int)==1. I am not able to understand.
If int has at least CHAR_BIT padding bits at its lowest address, your
function will BIG_ENDIAN if the padding bits happen to be set to 0, or
possibly some meaningless result if the padding bits are set to some
arbitrary value.


I really didn't understood that. Please can you explain in simpler words

Jun 24 '06 #15
"Money" <sp*********@gmail.com> writes:
Keith Thompson wrote:
If char is at least 16 bits, then it's possible that sizeof(int)==1;
in that case, int has no meaningful byte order, but your function will
return LITTLE_ENDIAN.


How is it possible for sizeof(int)==1. I am not able to understand.


char must be at least 8 bits (CHAR_BIT >= 8).

int must be at least 16 bits (CHAR_BIT * sizeof(int) >= 16). [1]

An implementation with CHAR_BIT==16 and sizeof(int)==1 would satisfy
these requirements.

Note that sizeof yields the size of its argument in bytes. In C, a
"byte" is by definition the size of a char, so sizeof(char) == 1 by
definition, however many bits that happens to be. (It's common these
days to use the term "byte" to mean exactly 8 bits, but that's not how
C uses the term; a better word for exactly 8 bits is "octet".)
If int has at least CHAR_BIT padding bits at its lowest address, your
function will BIG_ENDIAN if the padding bits happen to be set to 0, or
possibly some meaningless result if the padding bits are set to some
arbitrary value.


I really didn't understood that. Please can you explain in simpler words


Here's an example. Suppose CHAR_BIT==8, and sizeof(int)==4 (32 bits),
but only the high-order 24 bits contribute to the value; the low-order
8 bits are ignored. These 8 bits are called "padding bits". Suppose
the byte order is little-endian. Then the value 0x654321, for example,
would be represented by the byte values (0x00, 0x21, 0x43, 0x65), shown
from lowest to highest addresses within the word.

The proposed code sets an int to the value 1, which on our
hypothetical system would be represented as (0x00, 0x01, 0x00, 0x00).
It then looks at the first byte (at the lowest address) of the
representation. Seeing the value 0x00, it assumes, incorrectly, that
the 1 byte was stored at the other end of the word, and that the
machine is big-endian.

(I *think* I got this right.)

[1] The standard doesn't actually say direcly that int is at least 16
bits. It says that the range of values it can represent is at
least -32767 .. +32767. That, and the fact that a binary
represention is required, imply that it's at least 16 bits.

--
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.
Jun 24 '06 #16
On 2006-06-24, Money <sp*********@gmail.com> wrote:
Keith Thompson wrote:
If char is at least 16 bits, then it's possible that sizeof(int)==1;
in that case, int has no meaningful byte order, but your function will
return LITTLE_ENDIAN.


How is it possible for sizeof(int)==1. I am not able to understand.


int is guaranteed to be at least 16 bits. char is guaranteed to be
at least 8 bits, and sizeof (char) will always equal one. Therefore,
if both a char and an int are 16 bits (or any number above that),
sizeof (int) will equal one.
If int has at least CHAR_BIT padding bits at its lowest address, your
function will BIG_ENDIAN if the padding bits happen to be set to 0, or
possibly some meaningless result if the padding bits are set to some
arbitrary value.


I really didn't understood that. Please can you explain in simpler words


Padding bits are unused bits in a variable that don't actually hold
a value. They might contain metadata about the variable, and so if
they are corrupted, no one knows what will happen. (It won't be UB
that I know of, but it may not be what you expect.)

--
Andrew Poelstra < http://www.wpsoftware.net/blog >
To email me, use "apoelstra" at the above address.
I know that area of town like the back of my head.
Jun 24 '06 #17
Andrew Poelstra <ap*******@localhost.localdomain> writes:
[...]
Padding bits are unused bits in a variable that don't actually hold
a value. They might contain metadata about the variable, and so if
they are corrupted, no one knows what will happen. (It won't be UB
that I know of, but it may not be what you expect.)


Padding bits are defined only for integer types. (For other types,
the standard doens't say enough about their representation for the
concept to be meaningful.)

Padding bits do not contribute to the value of an object. Certain
values of padding bits might create a trap representation; accessing
an object that contains a trap representation invokes undefined
behavior.

--
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.
Jun 24 '06 #18
On Thu, 22 Jun 2006 21:44:42 -0700, Andrey Tarasevich
<an**************@hotmail.com> wrote in comp.lang.c:
Money wrote:
Here in this thread
http://groups.google.co.in/group/com...b0dbf76f3e02e3

Tydr Schnubbis in 3rd reply used %d for printing char's...isn't it
wrong?


On a platform with signed 'char' type, when 'char' values are passed as
arguments for '...' (ellipsis) parameters, they are first promoted to 'int'
values. So it's 'int' values that are actually passed. And there's nothing wrong
with using '%d' format specifier with 'int' values.

On a platform with unsigned 'char' type, it is possible that 'int' is not large
enough to hold all values of 'char' and 'char' will be promoted to 'unsigned
int' instead. In this particular case the code would lead to undefined behavior,
since it is illegal to use '%d' format specifier with 'unsigned int' values.


That is not entirely true. It is quite legal to pass an unsigned int
type to *printf() with a conversion specifier for the corresponding
signed type, and vice versa, provided that the value is within the
range of values that can be held in both types.

This snippet, assuming correct header inclusion:

void func()
{
int si = 2;
int ui = 2;

printf("\n%d %u\n", ui, si);
}

....must produce the output "2 2".

Passing a negative signed integer type to printf() with an unsigned
conversion specifier, or passing an unsigned integer type with a value
greater than TYPE_MAX with a signed conversion specifier is undefined.

You can also deduce from the standard that the common value range
defined solution actually applies to any function in C.

You can pass a signed int type (int or larger) to a function expecting
the corresponding unsigned type, or an unsigned type (int or larger)
to a function expecting the corresponding signed type, as long as the
value of type actually passed is in the range 0 through TYPE_MAX (not
UTYPE_MAX) inclusive.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jun 24 '06 #19

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

Similar topics

11
by: John Lenton | last post by:
Is there any reason python's printf-style formatting is missing the (C99) '%a' specifier? I'm sorry if this has been asked and answered before; I can't find it on google ('%a' is a very awkward...
4
by: Peter Ammon | last post by:
Does anyone ever write the arguments to printf()-like functions under the corresponding format specifier? printf("My name is %s and I am %u years old\n", name, age); If the arguments...
6
by: John L. | last post by:
I've seen several postings asking this, but no simple, clear answer. My C language reference book is deficient in this area. If I short i = 0; printf(">%2x<",i); I might resonably expect...
5
by: siliconwafer | last post by:
Hi All, What does a 'format specifier' do? Suppose I do, int a = 43; //decimal number printf("%x",a); I will get hex equivalent of 43. Does the format specifier do an implicit "decimal to hex"...
25
by: Digital Puer | last post by:
I'm getting a very weird bit corruption in a double. I am on an Intel Red Hat Linux box. uname -a returns: Linux foo.com 2.6.9-34.0.2.ELsmp #1 SMP Fri Jun 30 10:33:58 EDT 2006 i686 i686 i386...
8
by: FBM | last post by:
Hi there, I am puzzled with the behavior of my code.. I am working on a networking stuff, and debugging with eclipse (GNU gdb 6.6-debian).. The problem I am experiencing is the following: ...
8
by: asit | last post by:
plz fix the bug... #include <stdio.h> int main() { char ch; char i; printf("Enter an unsigned char : "); scanf("%d",&ch);
3
by: arnuld | last post by:
sizeof() operator gives 2 different types of size outputs :\ but I do not understand why: #include <stdio.h> #include <stdlib.h> int my_size( char );
15
by: Andreas Eibach | last post by:
.... but I have an unsigned long value in the printf. This warning came when I used gcc 4.x to compile. .... unsigned long offset = 0; .... Well OK, an "easy" way would be instead of printf...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
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: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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.