"Emmanuel Delahaye" <em***@YOURBRAnoos.fr> writes:
Jaspreet wrote on 16/09/05 : I was recently asked this question in an interview. Unfortunately I was
not able to answer it and the interviewer made a decision on my C
strengths (or weekness) based on this single question and that was a
sad end to my interview. Here is the program:
#include <stdio.h>
int main()
{
char *c ="abc";
int *i=(int*)c;
printf("%x", *i);
return 0;
}
The output is:
636261.
[...]
This question is idiotic. The interviewer is a idiot. The company that
hires such an idiotic is simply going to die. Try another place.
Not necessarily. Even though the behavior is undefined (nasal demons
and all that), it's not unreasonable to ask for an explanation of why
the program might happen to behave in some particular manner. This
kind of analysis can be important in debugging existing code.
I might even ask that kind of question in an interview myself. The
interviewee most likely to get the job would be the one who gave an
answer something like this:
This is horrible code that should never have been written this
way in the first place. The conversion of c to int* potentially
invokes undefined behavior if the string literal isn't properly
aligned for an int. As far as the C language standard is
concerned, there's nothing more to be said. But ...
If the conversion doesn't blow up, the dereference on the following
line may still do so. Assuming that "works", it assumes that
int is 4 bytes (the size of the string literal including the
trailing '\0'); if int is smaller than 4 bytes it won't grab
the whole string literal, and if int is bigger than 4 bytes it
will access memory beyond the string -- undefined behavior again.
The value of *i depends on the character encoding used and on the
byte ordering used for type int. It's possible, but unlikely,
that the value of *i will be a trap representation; if so, this
is undefined behavior again.
"int main()" is acceptable, but "int main(void)" is better.
"i" is a lousy name for a pointer variable. "c" isn't great
either.
The program should write a newline at the end of its output;
if it doesn't, the output may not appear on some systems.
If the output of the program is "636261", you can *probably*
reach the following conclusions:
The system has 8-bit chars and 32-bit ints.
The string literal happens to be aligned properly to be accessed
as an int. This could mean either than it's 4-byte aligned,
or that the system doesn't require 4-byte alignment for ints.
We could find out which by changing the initialization of i to
"(int*)(c+1) and seeing whether it then blows up.
The system uses an ASCII encoding for characters ('a'==61, 'b'==62,
'c'=63).
The system uses a little-endian representation for integers
(it's likely to be an x86).
If you really want a program that does this (for some reason),
you should shift each byte value into the result. Using memcpy()
would avoid the alignment issue, but not some of the other
portability issues.
If this code occurs in production software, it should be fixed as
soon as possible. Since any bug fix risks introducing new bugs,
the fix will have to go through the full testing cycle before
being released. (You do have a formal testing cycle, right?)
I wouldn't expect an interviewee, especially for an entry-level job,
to pick up on *all* these points, but anyone who can explain
reasonably well both why the code is bad and why it might produce the
observed output is a promising candidate.
Looking at it from the other side, if I were given this question in an
interview, I'd try to cover most of these points (at least until the
interviewer tells me to stop). If this is actually what the
interviewer is looking for, that's a good sign. If he expected me
just to explain why the code produces "636261", assuming that's the
only correct answer, I'm more likely to look elsewhere. On the other
other hand, if he didn't know about the problems with the code but
seems willing to learn, that may be an even better sign.
--
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.