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

Puzzling program

Good day group.

I was asked in an interview to explain the behavior of this program.

void main()
{
char *s = "abc";
int *i = (int *) s;
printf("%x", *i);
}

The question is: why is the output 636261? I don't think I know enough
about C to understand how the conversions between pointer types are
occurring.

Thanks for any help.

RD

Aug 8 '07
73 2727
Fr************@googlemail.com said:

<snip>
I believe it's undefined behavior to cast a char * to an unsigned *
and then dereference it,
Why do you believe this?

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 11 '07 #51
In article <At*********************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
>Rajeet Dalawal said:
>Good day group.

I was asked in an interview to explain the behavior of this program.

void main()
{
char *s = "abc";
int *i = (int *) s;
printf("%x", *i);
}

The question is: why is the output 636261?

No, it isn't. The question is: why is the interviewer asking you this
question? Is it to test your understanding that the program is
bug-ridden?
[snippage]
>If, on the other hand, he or she looks puzzled or disbelieving as you
explain the problems, thank him or her for the sandwiches and coffee,
make your excuses, and leave. You don't want to work there.
I think, if I ever get asked to interview a C programmer, I should use
this code or something very much like it.
The questions about it, of course, will be a little bit more detailed
than the one the OP posted:
(a) If you feed this to your favorite C implementation, what results will
you get?
(b) What information does this provide about the implementation?
(c.i) Is there a better way to write a program to get this information?
(c.ii) Is there a better way to get this information?

It should provide an excellent opportunity to determine levels of Clue
on both sides, and will also provide some information about how much
the interviewee understands about some of the things to be aware of when
moving between implementations.
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
Why not make it valid Pascal, Perl, Java, Basic, and Lisp also? Does your
employer know that your code will have to be completely rewritten when they
decide they want to compile it as a Java program? --Kevin Goodsell in CLC
Aug 11 '07 #52
On Aug 11, 1:18 am, Richard Heathfield <r...@see.sig.invalidwrote:
Francine.Ne...@googlemail.com said:

<snip>
I believe it's undefined behavior to cast a char * to an unsigned *
and then dereference it,

Why do you believe this?
OK... I'm a beginner at the whole quoting the Standard thing, but here
goes:

6.3.4 ... A pointer to an object or incomplete type can be converted
to a pointer to a different object or a different incomplete type. The
resulting pointer might not be valid if it is improperly aligned for
the type pointed to. It is guaranteed, however, that a pointer to an
object of a given alignment can be converted to a pointer to an object
of the same alignment or less strict alignment, and back again. The
result is equal to the original pointer. (An object of character type
has the least strict alignment.)

So converting char * to unsigned * means converting from char (which
has the least strict alignment) to something else (which therefore has
the same or more strict alignment). So there might be undefined
behavior, depending on the alignments in question. And if you have no
way of knowing when you write a line of code whether or not it will
produce undefined behavior when the program is run, it might be
prudent to assume the worst.

On the other hand, converting an unsigned * to a char * would be
guaranteed to "work", at least in the weak sense that you get a valid
pointer out. And you could also convert a char * to an unsigned *,
but /only if you knew it had arisen by a previous conversion from
unsigned * to char *./
>From a common sense point of view, let's say a char is 8 bits and
unsigned 32 bits (in some strange and exotic implementation X that
most people will never encounter :) ). Then the following code:

char c='a';
unsigned *p=(unsigned *) &c;
unsigned u=*p;

produces undefined behavior for another reason, i.e. the dereferencing
will read three bytes beyond the memory allocated for storing c.
<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999

Aug 11 '07 #53
On Fri, 10 Aug 2007 13:39:49 +0000, Christopher Benson-Manica wrote:
Keith Thompson <ks***@mib.orgwrote:
>But there are an infinite number of DS9K implementations. (They're
not required to exist physically, are they?)

Now that I think about it, they DO exist physically,

http://en.wikipedia.org/wiki/Many-worlds_interpretation
How do you think qsort is implemented on the DS9K? Whereas it was
originally intended that the 'q' stands for 'quick', the
implementers of DS9K interpreted is as 'quantum bogo'.

[OT, but in line with all the discussion about sorting algorithms
in another thread: The Jargon File claims that this implementation
of bogo-sort requires O(N), but to shuffle a deck with quantum
random numbers, one needs lg(N!) bits of quantum entropy, which
should take O(log(N!)) time, which is O(N*log(N)). I'll send an
e-mail to ESR pointing out the problem.]
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

Aug 11 '07 #54
On Fri, 10 Aug 2007 12:11:52 -0700, Keith Thompson wrote:
>Well, this may be more a case of "we're only coding for one specific
platform, and don't care about portability". (Not that that's
necessarily a good thing, but at least the code becomes "system
specific behavior" rather than "errors". Of course, what happens
when they decided to port to a similar, but 64-bit, platform?)

Here's the original program:

void main()
{
char *s = "abc";
int *i = (int *) s;
printf("%x", *i);
}
That's not just system-specific, it's *bad*. Even if you're assuming
a particular set of characteristics for the platform, I can think
of at least four corrections that should be made (add '#include
<stdio.h>', use 'int main(void)', use unsigned int rather than int,
and add a 'return 0;') Not caring about portability is no excuse
for these errors.
Even a newline at the end of the output wouldn't hurt.
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

Aug 11 '07 #55
Fr************@googlemail.com wrote:
>
On Aug 11, 1:18 am, Richard Heathfield <r...@see.sig.invalidwrote:
Francine.Ne...@googlemail.com said:

<snip>
I believe it's undefined behavior to cast a char * to an unsigned *
and then dereference it,
Why do you believe this?

OK... I'm a beginner at the whole quoting the Standard thing, but here
goes:

6.3.4 ... A pointer to an object or incomplete type can be converted
to a pointer to a different object or a different incomplete type. The
resulting pointer might not be valid if it is improperly aligned for
the type pointed to. It is guaranteed, however, that a pointer to an
object of a given alignment can be converted to a pointer to an object
of the same alignment or less strict alignment, and back again. The
result is equal to the original pointer. (An object of character type
has the least strict alignment.)

So converting char * to unsigned * means converting from char (which
has the least strict alignment) to something else (which therefore has
the same or more strict alignment). So there might be undefined
behavior, depending on the alignments in question. And if you have no
way of knowing when you write a line of code whether or not it will
produce undefined behavior when the program is run, it might be
prudent to assume the worst.

On the other hand, converting an unsigned * to a char * would be
guaranteed to "work", at least in the weak sense that you get a valid
pointer out. And you could also convert a char * to an unsigned *,
but /only if you knew it had arisen by a previous conversion from
unsigned * to char *./
From a common sense point of view, let's say a char is 8 bits and
unsigned 32 bits (in some strange and exotic implementation X that
most people will never encounter :) ). Then the following code:

char c='a';
unsigned *p=(unsigned *) &c;
unsigned u=*p;

produces undefined behavior for another reason, i.e. the dereferencing
will read three bytes beyond the memory allocated for storing c.
You can convert a (char *) to an (unsigned *),
in a correct C program, if you do what it takes
to make sure that the alignment issue is taken care of.
Chapter 8 of K&R shows how to use a union to force alignment.

--
pete
Aug 11 '07 #56

"Charlton Wilbur" <cw*****@chromatico.netwrote in message
news:87************@mithril.chromatico.net...
>
Fortunately, you have a DeathStation 2000. I ran it on my
DeathStation 3000, and I'm hoping my eyebrows grow back.
It's a good idea to unplug the main anti-planet beam generator before doing
debug runs.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Aug 11 '07 #57
pete wrote:

You can convert a (char *) to an (unsigned *),
in a correct C program, if you do what it takes
to make sure that the alignment issue is taken care of.
Chapter 8 of K&R shows how to use a union to force alignment.

The unsigned verison of a datatype is guaranteed to have the same
alignment as the signed type.

From the C99 draft:

6.2.5 Types

[#6] For each of the signed integer types, there is a
corresponding (but different) unsigned integer type |
(designated with the keyword unsigned) that uses the same
amount of storage (including sign information) and has the
same alignment requirements.

Brian
Aug 11 '07 #58
In article <5i*************@mid.individual.net>,
Default User <de***********@yahoo.comwrote:
>pete wrote:
>You can convert a (char *) to an (unsigned *),
in a correct C program, if you do what it takes
to make sure that the alignment issue is taken care of.
>The unsigned verison of a datatype is guaranteed to have the same
alignment as the signed type.
Yes, but (unsigned *) is a synonym for (unsigned int *)
and char and int are not guaranteed to have the same alignment
(and often do not.)
--
"It is important to remember that when it comes to law, computers
never make copies, only human beings make copies. Computers are given
commands, not permission. Only people can be given permission."
-- Brad Templeton
Aug 11 '07 #59
Fr************@googlemail.com said:
On Aug 11, 1:18 am, Richard Heathfield <r...@see.sig.invalidwrote:
> Francine.Ne...@googlemail.com said:

<snip>
I believe it's undefined behavior to cast a char * to an unsigned *
and then dereference it,

Why do you believe this?

OK... I'm a beginner at the whole quoting the Standard thing, but here
goes:
Skip it. I'm a beginner at this whole reading thing. I thought you said
"char * to an unsigned char *" - unsigned * is a completely different
animal. Sorry about that.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 11 '07 #60
Army1987 <ar******@NOSPAM.itwrites:
On Fri, 10 Aug 2007 12:11:52 -0700, Keith Thompson wrote:
[...]
>Here's the original program:

void main()
{
char *s = "abc";
int *i = (int *) s;
printf("%x", *i);
}
That's not just system-specific, it's *bad*. Even if you're assuming
a particular set of characteristics for the platform, I can think
of at least four corrections that should be made (add '#include
<stdio.h>', use 'int main(void)', use unsigned int rather than int,
and add a 'return 0;') Not caring about portability is no excuse
for these errors.
Even a newline at the end of the output wouldn't hurt.
Sure, but it would change the behavior of the program, and on an
implementation where a new-line is *not* required at the end of a text
stream, you might want to print the result without a new-line.

Remember, we're assuming that we don't care about portability.

The program is horrible in numerous ways; I'm merely trying to
distinguish different kinds of errors.

--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 11 '07 #61
On Sat, 11 Aug 2007 14:55:19 -0700, Keith Thompson wrote:
Army1987 <ar******@NOSPAM.itwrites:
>On Fri, 10 Aug 2007 12:11:52 -0700, Keith Thompson wrote:
[...]
>>Here's the original program:

void main()
{
char *s = "abc";
int *i = (int *) s;
printf("%x", *i);
}
That's not just system-specific, it's *bad*. Even if you're assuming
a particular set of characteristics for the platform, I can think
of at least four corrections that should be made (add '#include
<stdio.h>', use 'int main(void)', use unsigned int rather than int,
and add a 'return 0;') Not caring about portability is no excuse
for these errors.
Even a newline at the end of the output wouldn't hurt.

Sure, but it would change the behavior of the program, and on an
implementation where a new-line is *not* required at the end of a text
stream, you might want to print the result without a new-line.
<ot>On my system, a newline isn't required, but makes the prompt
appear on the same line as the output, which is not a good idea
(i. e. it looks bad).
</ot>
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

Aug 11 '07 #62
Army1987 <ar******@NOSPAM.itwrites:
On Sat, 11 Aug 2007 14:55:19 -0700, Keith Thompson wrote:
>Army1987 <ar******@NOSPAM.itwrites:
[...]
>>Even a newline at the end of the output wouldn't hurt.

Sure, but it would change the behavior of the program, and on an
implementation where a new-line is *not* required at the end of a text
stream, you might want to print the result without a new-line.
<ot>On my system, a newline isn't required, but makes the prompt
appear on the same line as the output, which is not a good idea
(i. e. it looks bad).
</ot>
Yes, but you might want the output to be written somewhere else (say,
to a file or another program), and it might just be more convenient
for the recipient not to have to deal with the new-line.
Non-portable, but perfectly reasonable in environments where it works.

--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 11 '07 #63
Walter Roberson wrote:
In article <5i*************@mid.individual.net>,
Default User <de***********@yahoo.comwrote:
pete wrote:
You can convert a (char *) to an (unsigned *),
in a correct C program, if you do what it takes
to make sure that the alignment issue is taken care of.
The unsigned verison of a datatype is guaranteed to have the same
alignment as the signed type.

Yes, but (unsigned *) is a synonym for (unsigned int *)
and char and int are not guaranteed to have the same alignment
(and often do not.)
Oh, I made the same mistake Richard did. Insufficient attention.

Brian
Aug 12 '07 #64
"Malcolm McLean" <re*******@btinternet.comwrites:
[...]
I used to think that the anti-Microsoft campaign was a bit
silly.
[...]

If you know this is off-topic, why did you post it here?

--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 12 '07 #65

"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
"Malcolm McLean" <re*******@btinternet.comwrites:
[...]
>I used to think that the anti-Microsoft campaign was a bit
silly.
[...]

If you know this is off-topic, why did you post it here?
OT tags are allowed for loosely C-related topics, of which Bill Gates'
billions is one. I do mention the evils of their compiler and OS versioning
strategy, again not topical but C-related.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Aug 12 '07 #66
>>>>"MMcL" == Malcolm McLean <re*******@btinternet.comwrites:

MMcLand you shouldn't listen to me for investment
MMcLadvice,

There was no danger of that, certainly.

MMcLHowever they are an excellent employer. Anyone who thinks
MMcLthat a spell at Microsoft won't do wonders for the bank
MMcLbalance and CV is an idiot.

This is not what people I know who have actually interviewed for
Microsoft and worked for Microsoft have told me; if you don't mind,
given your track record, I'll believe them rather than you, thanks.

Charlton

--
Charlton Wilbur
cw*****@chromatico.net
Aug 12 '07 #67
On Thu, 09 Aug 2007 15:40:19 -0700, Keith Thompson wrote:
Christopher Benson-Manica <at***@vinland.freeshell.orgwrites:
>Lew Pitcher <lp******@teksavvy.comwrote:
>>The answer is that the program is poorly written and invokes behaviour
that is not defined by the C standard. As "undefined behaviour" means
that anything can happen, the output value of 636\261 is just as valid
(and just as likely) as any other output.

Equally valid, yes, but hardly as likely, unless there are an infinite
number of DS9K implementations to smooth out the spike at 636261
produced by non-evil little endian ASCII implementations.

But there are an infinite number of DS9K implementations. (They're not
required to exist physically, are they?)
The perversity of the DS9K is such that a non-physical implementation of
it will spontaneously form as a physical manifestation, in the presence
of undefined behaviour, but only long enough to explode and thus maim or
kill the user. Later models incorporate a safety feature which only
allows this to occur when the user is also the developer, thus preserving
the user base but eliminating inattentive coders, thus improving the
computing world for all concerned.

Aug 12 '07 #68
Malcolm McLean wrote:
>
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
"Malcolm McLean" <re*******@btinternet.comwrites:
[...]
I used to think that the anti-Microsoft campaign was a bit
silly.
[...]

If you know this is off-topic, why did you post it here?
OT tags are allowed for loosely C-related topics, of which Bill Gates'
billions is one. I do mention the evils of their compiler and OS versioning
strategy, again not topical but C-related.
After all, Bill's own unsigned longs can't hold his net worth, and
his C compiler that I use doesn't support long long:

error C2632: 'long' followed by 'long' is illegal

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Aug 13 '07 #69
Kenneth Brody <ke******@spamcop.netwrote:
# Malcolm McLean wrote:
# >
# "Keith Thompson" <ks***@mib.orgwrote in message
# news:ln************@nuthaus.mib.org...
# "Malcolm McLean" <re*******@btinternet.comwrites:
# [...]
# I used to think that the anti-Microsoft campaign was a bit
# silly.
# [...]
#
# If you know this is off-topic, why did you post it here?
#
# OT tags are allowed for loosely C-related topics, of which Bill Gates'
# billions is one. I do mention the evils of their compiler and OS versioning
# strategy, again not topical but C-related.
#
# After all, Bill's own unsigned longs can't hold his net worth, and
# his C compiler that I use doesn't support long long:

$640K is enough money for anyone.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
OOOOOOOOOO! NAVY SEALS!
Aug 13 '07 #70
On Aug 13, 8:59 am, Kenneth Brody <kenbr...@spamcop.netwrote:
[snip]
After all, Bill's own unsigned longs can't hold his net worth, and
his C compiler that I use doesn't support long long:

error C2632: 'long' followed by 'long' is illegal
Support for long long has been available since the release of VC++.NET
2003 in 2002 (5 years ago).
Maybe it's time to upgrade.
[snip]

Aug 13 '07 #71

"user923005" <dc*****@connx.comwrote in message
news:11**********************@w3g2000hsg.googlegro ups.com...
On Aug 13, 8:59 am, Kenneth Brody <kenbr...@spamcop.netwrote:
[snip]
>After all, Bill's own unsigned longs can't hold his net worth, and
his C compiler that I use doesn't support long long:

error C2632: 'long' followed by 'long' is illegal

Support for long long has been available since the release of VC++.NET
2003 in 2002 (5 years ago).
Maybe it's time to upgrade.
[snip]
That's what Bill's minions told me.
Why should I have to pay lots of money and then trawl through my programs
looking for incompatibiliites, when I've already bought a perfectly good
compiler?

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Aug 13 '07 #72
On Mon, 13 Aug 2007 22:59:08 +0100, in comp.lang.c , "Malcolm McLean"
<re*******@btinternet.comwrote:
>
"user923005" <dc*****@connx.comwrote in message
news:11**********************@w3g2000hsg.googlegr oups.com...
>On Aug 13, 8:59 am, Kenneth Brody <kenbr...@spamcop.netwrote:
[snip]
>> error C2632: 'long' followed by 'long' is illegal

Maybe it's time to upgrade.
Why should I have to pay lots of money and then trawl through my programs
looking for incompatibiliites, when I've already bought a perfectly good
compiler?
No reason, if you don't want long long.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Aug 13 '07 #73
Mark McIntyre wrote:
>
On Mon, 13 Aug 2007 22:59:08 +0100, in comp.lang.c , "Malcolm McLean"
<re*******@btinternet.comwrote:

"user923005" <dc*****@connx.comwrote in message
news:11**********************@w3g2000hsg.googlegro ups.com...
On Aug 13, 8:59 am, Kenneth Brody <kenbr...@spamcop.netwrote:
[snip]
error C2632: 'long' followed by 'long' is illegal

Maybe it's time to upgrade.
Why should I have to pay lots of money and then trawl through my programs
looking for incompatibiliites, when I've already bought a perfectly good
compiler?

No reason, if you don't want long long.
I have very little need for long long, and the incompatibilities
far outweigh the one use I have for them. And for that, I simply
use my own typedef which is set to "__int64" for MSVC.

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

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

Similar topics

1
by: Robert Brown | last post by:
I have a deadlock that's happening on one oracle instance but cannot be reproduced on any other. It is always caused by the same SQL statement colliding with itself and only happens under very high...
1
by: Alvin | last post by:
Note: Source code and compile commands are at the bottom. I've spent some time with a friend making a nice and simple to use OOPified C++ networking layer for TCP that works on multiple...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
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
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: 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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
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.