Puzzling program

M

Malcolm McLean

I'd never like to work for a company where interviewers declare main
as a void function...
Microsoft.
They were offering stock options worth several million dollars to some of
their programmers.
(Cue lots of posts from people with less than 1 million dollars saying those
Microsoft grapes are sour).
 
D

Dave Vandervies

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
 
K

Kelsey Bjarnason

[snips]

Microsoft.
They were offering stock options worth several million dollars to some
of their programmers.
(Cue lots of posts from people with less than 1 million dollars saying
those Microsoft grapes are sour).

Dunno about sour, but no, I would *not* want to work for MS, for many
reasons. Perhaps _you_ are for sale to the highest bidder; that doesn't
mean everyone is.
 
F

Francine.Neary

(e-mail address removed) said:



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.
 
A

Army1987

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.]
 
A

Army1987

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.
 
P

pete

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 *./

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.
 
M

Malcolm McLean

Charlton Wilbur said:
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.
 
D

Default User

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
 
W

Walter Roberson

pete wrote:
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.)
 
R

Richard Heathfield

(e-mail address removed) said:
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.
 
K

Keith Thompson

Army1987 said:
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.
 
A

Army1987

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>
 
K

Keith Thompson

Army1987 said:
<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.
 
C

Charlton Wilbur

KB> [snips]

KB> Dunno about sour, but no, I would *not* want to work for MS,
KB> for many reasons. Perhaps _you_ are for sale to the highest
KB> bidder; that doesn't mean everyone is.

If I reasonably thought that I'd get paid a couple million dollars for
a year's work, I'd even work at Microsoft: a year of work I can't
stand in exchange for permanent financial freedom is a better deal
than ongoing employment with some of the lesser mediocrities I've
worked with.

But Microsoft doesn't offer a couple million dollars for a year's
work; it offers a reasonable but not ridiculous wage. It takes a
lightning strike to make stock options worth millions, and it's highly
unlikely that unless the speculative bubble returns that tech stock
options are going to make millions of dollars for any employee.
Anybody who treats stock options as real money in a salary negotiation
is an incurable optimist or a financial fool or both.

Charlton
 
D

Default User

Walter said:
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
 
M

Malcolm McLean

Charlton Wilbur said:
If I reasonably thought that I'd get paid a couple million dollars for
a year's work, I'd even work at Microsoft: a year of work I can't
stand in exchange for permanent financial freedom is a better deal
than ongoing employment with some of the lesser mediocrities I've
worked with.
I used to think that the anti-Microsoft campaign was a bit silly. Until I
bought Vista, and my VC++6.0 compiler broake, obviously deliberately.
Microsoft's attitude was arrogant and unhelpful, and I still haven't
recovered from the setback - BASICdraw has not been ported to the new
system, so I haven't been able to release bug fixes or updates.
But Microsoft doesn't offer a couple million dollars for a year's
work; it offers a reasonable but not ridiculous wage. It takes a
lightning strike to make stock options worth millions, and it's highly
unlikely that unless the speculative bubble returns that tech stock
options are going to make millions of dollars for any employee.
Anybody who treats stock options as real money in a salary negotiation
is an incurable optimist or a financial fool or both.
Their stock was bid up to a very optimistic level, in the process making
millionaires of many employees who held options. Whilst I stupidly put money
into the stock market last month, at the peak (though into a
counter-cyclical stock), and you shouldn't listen to me for investment
advice, Microsoft have big problems ahead with consumer rejection of Vista,
because it won't play pirated content - I did use to feel sorry for Bill
Gates, but not any more. Not after breaking BASICdraw. I think the gloss
will come off their shares, and they'll have to pay employees with real
money rather than options.

However they are an excellent employer. Anyone who thinks that a spell at
Microsoft won't do wonders for the bank balance and CV is an idiot.
 
M

Malcolm McLean

Keith Thompson said:
Malcolm McLean said:
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.
 
C

Charlton Wilbur

MMcL> and you shouldn't listen to me for investment
MMcL> advice,

There was no danger of that, certainly.

MMcL> However they are an excellent employer. Anyone who thinks
MMcL> that a spell at Microsoft won't do wonders for the bank
MMcL> balance 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
 

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
474,431
Messages
2,571,678
Members
48,796
Latest member
Greg L.

Latest Threads

Top